티스토리 뷰

 

 

얼마전에 비슷한 주제로 글을 하나 썼었다.

 

위 내용은 AWS S3 SDK 1.x 버전을 기준으로 작성했었다.

 

왜 1.x 버전을 선택했냐를 묻는다면 별 이유가 없었다.

 

그냥 구글링을하다가 가장 먼저 나왔던걸 사용했었는데, 이게 의외의 곳에서 문제를 일으켰다.

 

로컬에선 정상적으로 동작하는데, dev 서버에 배포되면 S3 SDK 매서드들이 Access Deny 문제로 사용이 불가능해졌다.

 

dev 서버에 default로 지정된 AWS의 credential이 있는데도, 계속해서 문제를 일으켰는데 알고보니 SDK 버전이 문제였다.

https://github.com/aws/aws-sdk-java-v2/issues/1470

 

요약하면 eks 환경에서 디폴트로 지정된 경로의 credential을 가져올 수 없으니 SDK 2.x 버전을 써라이다.

 

무튼 위 문제로 속이 좀 썩었지만, 2.0 SDK를 써보니 많은 장점이 있어서 사용법을 소개해보려고 한다.

 

우선 설치부터 시작!

 

설치

build.gradle

implementation platform('software.amazon.awssdk:bom:2.20.56')
implementation 'software.amazon.awssdk:s3'

 

SDK APIs

1.x랑 가장 큰 차이점은 각 API들마다 ReqeustObject들이 생겼고, 각 Object별로 builder가 생겨서 요청 객체를 조금 더 이쁘게 생성할 수 있었다.

 

하나씩 알아보자.

 

Configuration

리전을 설정한 client를 전역으로 설정하고 사용하기위해 configuration을 설정했다. 

@Configuration
public class S3Config {

    @Bean
    public S3Client defaultS3Client() {
        return S3Client.builder().region(Region.AP_NORTHEAST_2).build();
    }
}

.aws아래의 credential을 사용하고 싶지 않다면, 별도의 추가 설정이 필요하니 아래 URL을 참고하면 좋을 것 같다.

https://stackoverflow.com/questions/75881298/s3-client-creation-with-aws-sdk-for-java-2-x

 

업로드(Put)

public void uploadFileToS3(String s3Path, File file) {
    PutObjectRequest putObjectRequest = PutObjectRequest.builder()
                                                        .bucket(dataBucketName)
                                                        .key(s3Path)
                                                        .acl(ObjectCannedACL.BUCKET_OWNER_FULL_CONTROL)
                                                        .build();

    s3Client.putObject(putObjectRequest, RequestBody.fromFile(file));

}

bucket은 S3 버킷명이고, key는 파일명을 포함한 full URL이다.

 

acl은 파일 생성시 파일이 어떤 권한을 가질지 명시한다.

 

SDK 1.x코드와 비교해보면, 요청 객체 생성이 확실히 간결해졌다.

PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, fileName, uploadFile);

s3Client.putObject(putObjectRequest);

 

다운로드

public File getS3Data(String s3Path, String fileName) {
    GetObjectRequest objectRequest = GetObjectRequest.builder()
                                                        .bucket(dataBucketName)
                                                        .key(s3Path)
                                                        .build();

    s3Client.getObject(objectRequest, ResponseTransformer.toFile(fileName));

    return new File(outputFilePath.toString());
}

이렇게 작성할 시 src 아래에 파일이 생성되니 별도의 경로를 지정하도록 하자.

 

삭제

public void deleteS3webEditorImg(String s3Path) {
    DeleteObjectRequest deleteObjectRequest = DeleteObjectRequest.builder()
                                                            .bucket(webEditorBucketName)
                                                            .key(s3Path)
                                                            .build();
    s3Client.deleteObject(deleteObjectRequest);
}

 

복사

public void copyWebEditorImageToS3(String fromPath, String toPath) {
    CopyObjectRequest copyObjectRequest = CopyObjectRequest.builder()
                                                            .sourceBucket(webEditorBucketName)
                                                            .destinationBucket(webEditorBucketName)
                                                            .sourceKey(fromPath)
                                                            .destinationKey(toPath)
                                                            .acl(ObjectCannedACL.BUCKET_OWNER_FULL_CONTROL)
                                                            .build();

    s3Client.copyObject(copyObjectRequest);

}

 

마치며

생각지도 못한 에러 때문에 SDK를 바꾸게 됐지만 결론적으로 최신 버전의 SDK를 사용하게 됐다.

 

그리고 의외의 곳에서 부가적인 효과를 얻게 됐는데,

 

기존 CLI + 자바 exec를 통해 cmd에서 쓰도록 하는 것보다 속도면에서도 개선이 됐고, 하드코딩을 많이 덜어낼 수 있어서 가독성 면에서도 큰 이점을 얻을 수 있었다.

 

이렇게보면 에러를 마주치는게 꼭 나쁜 것만은 아니다..

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
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
글 보관함