-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #53 from kakao-tech-campus-2nd-step3/develop
Develop
- Loading branch information
Showing
13 changed files
with
310 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
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
20 changes: 20 additions & 0 deletions
20
src/main/java/poomasi/global/config/aws/AwsProperties.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,20 @@ | ||
package poomasi.global.config.aws; | ||
|
||
import lombok.Data; | ||
import org.springframework.boot.context.properties.ConfigurationProperties; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Data | ||
@Component | ||
@ConfigurationProperties("aws") | ||
public class AwsProperties { | ||
private String access; | ||
private String secret; | ||
private S3Properties s3; | ||
|
||
@Data | ||
public static class S3Properties { | ||
private String bucket; | ||
private String region; | ||
} | ||
} |
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,52 @@ | ||
package poomasi.global.config.s3; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.beans.factory.annotation.Qualifier; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import poomasi.global.config.aws.AwsProperties; | ||
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; | ||
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider; | ||
import software.amazon.awssdk.regions.Region; | ||
import software.amazon.awssdk.services.s3.S3AsyncClient; | ||
import software.amazon.awssdk.services.s3.S3Client; | ||
import software.amazon.awssdk.services.s3.presigner.S3Presigner; | ||
|
||
@Configuration | ||
@RequiredArgsConstructor | ||
public class S3Config { | ||
|
||
private final AwsProperties awsProperties; | ||
|
||
@Bean("awsCredentials") | ||
public AwsCredentialsProvider awsCredentials() { | ||
return DefaultCredentialsProvider.create(); | ||
} | ||
|
||
@Bean | ||
public S3Presigner s3Presigner(@Qualifier("awsCredentials") AwsCredentialsProvider awsCredentials) { | ||
return S3Presigner | ||
.builder() | ||
.credentialsProvider(awsCredentials) | ||
.region(Region.of(awsProperties.getS3().getRegion())) | ||
.build(); | ||
} | ||
|
||
@Bean("s3AsyncClient") | ||
public S3AsyncClient s3AsyncClient(@Qualifier("awsCredentials") AwsCredentialsProvider awsCredentials) { | ||
return S3AsyncClient | ||
.builder() | ||
.credentialsProvider(awsCredentials) | ||
.region(Region.of(awsProperties.getS3().getRegion())) | ||
.build(); | ||
} | ||
|
||
@Bean("s3Client") | ||
public S3Client s3Client(@Qualifier("awsCredentials") AwsCredentialsProvider awsCredentials) { | ||
return S3Client | ||
.builder() | ||
.credentialsProvider(awsCredentials) | ||
.region(Region.of(awsProperties.getS3().getRegion())) | ||
.build(); | ||
} | ||
} |
80 changes: 80 additions & 0 deletions
80
src/main/java/poomasi/global/config/s3/S3PresignedUrlService.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 poomasi.global.config.s3; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.stereotype.Service; | ||
import poomasi.global.util.EncryptionUtil; | ||
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 java.time.Duration; | ||
import java.time.LocalDateTime; | ||
import java.time.format.DateTimeFormatter; | ||
import java.util.Map; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
@Slf4j | ||
public class S3PresignedUrlService { | ||
private final S3Presigner s3Presigner; | ||
private final EncryptionUtil encryptionUtil; | ||
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); | ||
private static final Long SIGNATURE_DURATION = 10L; | ||
|
||
|
||
public String createPresignedGetUrl(String bucketName, String keyName) { | ||
GetObjectRequest objectRequest = GetObjectRequest.builder() | ||
.bucket(bucketName) | ||
.key(keyName) | ||
.build(); | ||
|
||
GetObjectPresignRequest presignRequest = GetObjectPresignRequest.builder() | ||
.signatureDuration(Duration.ofMinutes(SIGNATURE_DURATION)) | ||
.getObjectRequest(objectRequest) | ||
.build(); | ||
|
||
PresignedGetObjectRequest presignedRequest = s3Presigner.presignGetObject(presignRequest); | ||
log.info("Presigned URL: [{}]", presignedRequest.url().toString()); | ||
log.info("HTTP method: [{}]", presignedRequest.httpRequest().method()); | ||
|
||
return presignedRequest.url().toExternalForm(); | ||
|
||
} | ||
|
||
public String createPresignedPutUrl(String bucketName, String keyPrefix, Map<String, String> metadata) { | ||
LocalDateTime now = LocalDateTime.now(); | ||
String date = now.format(DATE_FORMATTER); | ||
String encodedTime = encryptionUtil.encodeTime(now).substring(0, 10); | ||
|
||
String keyName = String.format("%s/%s/%s.jpg", keyPrefix, date, encodedTime); | ||
|
||
|
||
PutObjectRequest objectRequest = PutObjectRequest.builder() | ||
.bucket(bucketName) | ||
.key(keyName) | ||
.metadata(metadata) | ||
.build(); | ||
|
||
PutObjectPresignRequest presignRequest = PutObjectPresignRequest.builder() | ||
.signatureDuration(Duration.ofMinutes(SIGNATURE_DURATION)) | ||
.putObjectRequest(objectRequest) | ||
.build(); | ||
|
||
|
||
PresignedPutObjectRequest presignedRequest = s3Presigner.presignPutObject(presignRequest); | ||
String myURL = presignedRequest.url().toString(); | ||
log.info("Presigned URL to upload a file to: [{}]", myURL); | ||
log.info("HTTP method: [{}]", presignedRequest.httpRequest().method()); | ||
|
||
return presignedRequest.url().toExternalForm(); | ||
} | ||
|
||
|
||
} | ||
|
||
// reference: https://docs.aws.amazon.com/ko_kr/AmazonS3/latest/userguide/example_s3_Scenario_PresignedUrl_section.html |
25 changes: 25 additions & 0 deletions
25
src/main/java/poomasi/global/config/s3/TestController.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,25 @@ | ||
package poomasi.global.config.s3; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RestController | ||
@RequiredArgsConstructor | ||
public class TestController { | ||
private final S3PresignedUrlService s3PresignedUrlService; | ||
|
||
@GetMapping("/presigned-url-put") | ||
public ResponseEntity<?> presignedUrlPut() { | ||
String presignedPutUrl = s3PresignedUrlService.createPresignedPutUrl("poomasi", "test", null); | ||
return ResponseEntity.ok(presignedPutUrl); | ||
} | ||
|
||
@GetMapping("/presigned-url-get") | ||
public ResponseEntity<?> presignedUrlGet(@RequestParam String keyname) { | ||
String presignedGetUrl = s3PresignedUrlService.createPresignedGetUrl("poomasi", keyname); | ||
return ResponseEntity.ok(presignedGetUrl); | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package poomasi.global.util; | ||
|
||
import org.springframework.stereotype.Component; | ||
import poomasi.global.error.ApplicationError; | ||
import poomasi.global.error.ApplicationException; | ||
|
||
import java.nio.charset.StandardCharsets; | ||
import java.security.MessageDigest; | ||
import java.time.LocalDateTime; | ||
import java.util.Base64; | ||
|
||
@Component | ||
public class EncryptionUtil { | ||
|
||
public String encodeTime(LocalDateTime time) { | ||
try { | ||
String timeString = time.toString(); | ||
byte[] hash = MessageDigest.getInstance("SHA-256") | ||
.digest(timeString.getBytes(StandardCharsets.UTF_8)); | ||
return Base64.getUrlEncoder().withoutPadding().encodeToString(hash); | ||
} catch (Exception e) { | ||
throw new ApplicationException(ApplicationError.ENCRYPT_ERROR); | ||
} | ||
} | ||
} |
Oops, something went wrong.