티스토리 뷰
개요
지난 번 MinIO를 설명하면서 S3와 완벽히 호환한다고 이야기 하였으므로, 이에 대해 AWS S3 JAVA SDK v2를 이용한 샘플 코드를 설명한다.
설정
- S3의 CredentialsProvider는 여러 가지가 존재하지만 application.properties를 활용한 설정을 사용하는 방법과 DefaultProvider 사용하는 방법을 유연하게 전환할 수 있는 샘플 코드를 설명한다.
S3Properties.java
@Data
@Configuration
@ConfigurationProperties(prefix = "s3")
public class S3Properties {
private String endpointUrl;
private String accessKeyId;
private String secretAccessKey;
private String region;
}
- ConfigurationProperties를 이용하여 "application.properties"에 설정한 아래의 설정들을 가져와 설정한다.
- s3.endpoint-url : S3 API URL을 설정한다.
- s3.access-key-id : S3에서 발급한 Access Key를 설정한다.
- s3.secret-access-key : 위의 Access key의 Secrey Key를 설정한다.
- s3.region : S3 연결 리전 명칭을 설정한다.
S3Config.java
private AwsCredentialsProvider getAwsCredentialsProvider() {
if (StringUtils.isNotBlank(this.s3Properties.getAccessKeyId()) && StringUtils.isNotBlank(this.s3Properties.getSecretAccessKey())) {
return StaticCredentialsProvider.create(
AwsBasicCredentials.create(this.s3Properties.getAccessKeyId(), this.s3Properties.getSecretAccessKey()));
} else {
return DefaultCredentialsProvider.create();
}
}
- S3Properties에서 설정한 정보를 이용하여 CredentialsProvider를 동적으로 설정한다.
- "AccessKeyId"와 "SecretAccessKey"를 설정한 경우, AwsBasicCredentials를 이용한 설정을 사용하도록한다.
- DefaultCredentialsProvider는 SDK 내에서 동적으로 어떤 CredentialsProvider를 사용할지 아래의 순서대로 확인하여 인증 가능하도록 한다.
- SystemPropertyCredentialsProvider : JAVA 시스템 설정 내 "aws.accessKeyId"와 "aws.secretAccessKey"를 이용한다.
- EnvironmentVariableCredentialsProvider : 환경 변수로 설정된 "AWS_ACCESS_KEY_ID"와 "AWS_SECRET_ACCESS_KEY"를 사용한다.
- WebIdentityTokenFileCredentialsProvider : JAVA 시스템 설정 내 혹은 환경 변수에 존재하는 Web ID 토큰을 사용한다.
- ProfileCredentialsProvider : AWS 인증 정보를 저장하는 기본 파일인 '~/.aws/credentials'를 이용해 AWS SDK와 CLI와 설정을 공유한다.
- ContainerCredentialsProvider : security manager가 해당 변수에 접근할 권한을 가진 경우, Amazon EC2 컨테이너 서비스에 "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" 환경 변수가 설정하여 사용한다.
- InstanceProfileCredentialsProvider : Amazon EC2 메타 서비스를 이용하여 인스턴스 프로필을 가져온다.
public S3Client s3Client() {
S3ClientBuilder s3ClientBuilder = S3Client.builder().credentialsProvider(this.getAwsCredentialsProvider());
if (StringUtils.isNotBlank(this.s3Properties.getEndpointUrl())) {
s3ClientBuilder.endpointOverride(URI.create(this.s3Properties.getEndpointUrl()));
}
if (StringUtils.isNotBlank(this.s3Properties.getRegion())) {
s3ClientBuilder.region(Region.of(this.s3Properties.getRegion()));
}
return s3ClientBuilder.build();
}
- S3ClientBuilder를 이용하여 위에서 사용된 기본 방법을 이용하여 CredentialsProvider를 설정한다.
- "application.properties" 내 "EndpointUrl", "Region" 정보가 있을 때는 해당 정보를 보도록 하고 없으면 위에서 설명한 DefaultCredentialsProvider에서 제공하는 방법으로 주입 받도록 처리한다.
- "EndpointUrl"을 설정하지 않으면 "Region" 내 "EndpointUrl" 사용하기 때문에 "Region"은 반드시 설정해야 하며, 설정되지 않은 경우 오류가 발생한다.
실행
S3Service.java
listObjects
public List<S3Object> listObjects(String bucket, int size) {
try {
return this.s3Client.listObjects(ListObjectsRequest.builder().bucket(bucket).maxKeys(size).build())
.contents();
} catch (Exception e) {
e.printStackTrace();
return Collections.emptyList();
}
}
- S3의 특정 bucket에 존재하는 Object 정보 size 단위로 페이징 처리하여 가져오는 listObjects를 이용한 샘플 코드이다.
getObject
public ResponseEntity<ByteArrayResource> getObject(String bucket, String key) {
try {
ResponseInputStream<GetObjectResponse> responseInputStream = this.s3Client.getObject(GetObjectRequest.builder().bucket(bucket).key(key).build());
GetObjectResponse getObjectResponse = responseInputStream.response();
return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + key)
.contentType(MediaType.valueOf(responseInputStream.response().contentType()))
.contentLength(getObjectResponse.contentLength())
.lastModified(getObjectResponse.lastModified())
.body(new ByteArrayResource(responseInputStream.readAllBytes()));
} catch (Exception e) {
e.printStackTrace();
return ResponseEntity.internalServerError().build();
}
}
- S3에 생성된 bucket 내 key에 해당하는 Object 정보를 가져와서 Reponse로 해당 파일을 반환하는 getObject를 활용한 샘플 코드이다.
- GetObjectResponse를 반환하여 Object 정보를 여러 방법거나, OutputStream을 이용해 파일 생성 등 다양하게 활용 가능하다.
putObject
public boolean putObject(String bucket, String key, String path) {
try {
return this.s3Client.putObject(PutObjectRequest.builder().bucket(bucket).key(key).build(), Paths.get(path))
.sdkHttpResponse()
.isSuccessful();
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
- S3에 생성된 bucket 내 key에 해당하는 Object를 시스템 내 path에 위치한 파일로 덮어쓰는 putObject를 이용한 샘플 코드이다.
- S3는 기본적으로 key에 Object를 설정하므로, Versioning 설정을 하지 않은 상태라면 기존 파일 정보를 백업하지 않고 덮어써진다.
copyObject
public boolean copyObject(String sourceBucket, String sourceKey, String destinationBucket, String destinationKey) {
try {
return this.s3Client
.copyObject(CopyObjectRequest.builder()
.sourceBucket(sourceBucket).sourceKey(sourceKey)
.destinationBucket(destinationBucket).destinationKey(destinationKey).build())
.sdkHttpResponse()
.isSuccessful();
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
- S3에 생성된 sourceBucket 내 sourceKey에 해당하는 Object를 destinationBucket의 destinationKey로 복사하는 putObject를 이용한 샘플 코드이다.
deleteObject
public boolean deleteObject(String bucket, String key) {
try {
return this.s3Client.deleteObject(DeleteObjectRequest.builder().bucket(bucket).key(key).build())
.sdkHttpResponse()
.isSuccessful();
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
- S3에 생성된 bucket 내 key에 해당하는 Object를 삭제하는 deleteObject를 이용한 샘플 코드이다.
여담
- Spring Boot 3.2 버전에서는 Spring Framework 6.1 버전을 도입하여 "@RequestMapping"과 관련한 어노테이션들에서 "@PathVariable" 어노테이션을 사용할 때, "name"과 "value"으로 어느 값을 변수에 할당할지 명시하지 않으면 "Ensure that the compiler uses the '-parameters' flag." 오류가 발생한다.
- Spring Framework가 5에서 6으로 버전이 올라가면서 "LocalVariableTableParameterNameDiscoverer"가 삭제되어 컴파일 단계에서 매개 변수 이름을 추론하는 기능을 기본적으로 제공하지 않으므로, 사용하고자 하는 경우 컴파일 설정에 Java 8 이상에서는 '-parameters', Kotlin은 '-java-parameters' 플래그를 추가하여 해당 기능을 사용할 수 있도록 변경되었다.
소스
Sample Code는 여기에서 확인 가능합니다.
이전
2024.11.08 - [개발] - AWS S3와 완벽히 호환하는 MinIO Object Storage에 대한 설명
AWS S3와 완벽히 호환하는 MinIO Object Storage에 대한 설명
개요MinIO는 고성능 Enterprise Object Store(EOS)로 Amazon Web Services S3 기능을 모두 지원하는 객체 스토리지 솔루션이다.주요 라이센스로는 AGPLv3 라이센스로 Open Source 버전과 비교적 자유적인 이점을 제공
gracefulsoul.tistory.com
참고
- AWS SDK for Java - Developer Guide for version 2.x
- Spring GitHub - Upgrading to Spring Framework 6.x #Parameter Name Retention
Work with Amazon S3 - AWS SDK for Java 2.x
From version 2.18.x and onward, the AWS SDK for Java 2.x uses virtual hosted-style addressing when including an endpoint override. This applies as long as the bucket name is a valid DNS label. Call the forcePathStyle method with true in your client builder
docs.aws.amazon.com
Upgrading to Spring Framework 6.x
Spring Framework. Contribute to spring-projects/spring-framework development by creating an account on GitHub.
github.com
'개발' 카테고리의 다른 글
Java Garbage Collection에 대한 설명 (0) | 2024.11.12 |
---|---|
Java Generic에 대한 설명 (6) | 2024.11.11 |
Spring Cache에 대한 설명과 예제 (0) | 2024.11.10 |
Jdeps와 Jlink를 이용하여 경량화된 Custom JRE를 사용하는 Dockerizng으로 CI/CD 성능 최적화 (2) | 2024.11.09 |
AWS S3와 완벽히 호환하는 MinIO Object Storage에 대한 설명 (2) | 2024.11.08 |
- Total
- Today
- Yesterday
- java
- JWT
- Spring
- mybtis
- sample code
- nosuchmethodexception
- functional programing
- bean
- async
- extensibility
- repmgr
- graecful shutdown
- javascript
- point cut
- barman
- hot-backup
- minio
- bouncy castle
- docker
- await
- Promise
- jdeps
- object storage
- ASYNCHRONOUS
- db lank
- patametertype
- PostgreSQL
- aws s3
- reusability
- multi stage biluild
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |