Java 세계에서 S3 버킷에 콘텐츠를 업로드하는 몇 가지 좋은 방법이 있습니다. 이 기사에서는 jclouds 라이브러리 가 이러한 목적을 위해 제공하는 것을 살펴볼 것입니다.
jclouds, 특히 이 기사에서 논의된 API를 사용하려면 이 간단한 Maven 의존성 을 프로젝트의 pom에 추가해야 합니다.
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-allblobstore</artifactId>
<version>1.5.10</version>
</dependency>
1. Amazon S3에 업로드
이러한 API에 액세스하기 위한 첫 번째 단계는 BlobStoreContext 를 만드는 것입니다 .
BlobStoreContext context =
ContextBuilder.newBuilder("aws-s3").credentials(identity, credentials)
.buildView(BlobStoreContext.class);
이는 Amazon S3와 같은 일반 키-값 스토리지 서비스에 대한 진입점을 나타내지만 이에 국한되지 않습니다.
보다 구체적인 S3 전용 구현의 경우 컨텍스트를 유사하게 생성할 수 있습니다.
BlobStoreContext context =
ContextBuilder.newBuilder("aws-s3").credentials(identity, credentials)
.buildView(S3BlobStoreContext.class);
그리고 더 구체적으로:
BlobStoreContext context =
ContextBuilder.newBuilder("aws-s3").credentials(identity, credentials)
.buildView(AWSS3BlobStoreContext.class);
인증된 컨텍스트가 더 이상 필요하지 않은 경우 연결된 모든 리소스(스레드 및 연결)를 해제하려면 해당 컨텍스트를 닫아야 합니다.
2. jclouds의 4가지 S3 API
jclouds 라이브러리는 단순하지만 유연하지 않은 것부터 복잡하고 강력한 것에 이르기까지 S3 버킷에 콘텐츠를 업로드하기 위해 BlobStoreContext 를 통해 얻은 네 가지 API를 제공합니다 . 가장 간단한 것부터 시작합시다.
2.1. Map API 를 통해 업로드
jclouds를 사용하여 S3 버킷과 상호 작용할 수 있는 가장 쉬운 방법은 해당 버킷을 맵으로 나타내는 것입니다. API는 컨텍스트에서 가져옵니다.
InputStreamMap bucket = context.createInputStreamMap("bucketName");
그런 다음 간단한 HTML 파일을 업로드하려면:
bucket.putString("index1.html", "<html><body>hello world1</body></html>");
InputStreamMap API는 파일, 원시 바이트와 같은 여러 다른 유형의 PUT 작업을 단일 및 대량 모두에 대해 노출합니다 .
간단한 통합 테스트를 예로 사용할 수 있습니다.
@Test
public void whenFileIsUploadedToS3WithMapApi_thenNoExceptions() {
BlobStoreContext context =
ContextBuilder.newBuilder("aws-s3").credentials(identity, credentials)
.buildView(AWSS3BlobStoreContext.class);
InputStreamMap bucket = context.createInputStreamMap("bucketName");
bucket.putString("index1.html", "<html><body>hello world1</body></html>");
context.close();
}
2.2. BlobMap 을 통해 업로드
간단한 Map API를 사용하는 것은 간단하지만 궁극적으로 제한적입니다. 예를 들어 업로드되는 콘텐츠에 대한 메타데이터를 전달할 방법이 없습니다. 더 많은 유연성과 사용자 정의가 필요한 경우 Map를 통해 S3에 데이터를 업로드하는 이 단순화된 접근 방식으로는 더 이상 충분하지 않습니다.
다음으로 살펴볼 API는 Blob Map API입니다. 이것은 컨텍스트에서 가져옵니다.
BlobMap bucket = context.createBlobMap("bucketName");
API를 통해 클라이언트는 Content – Length , Content-Type , Content-Encoding , eTag 해시 등과 같은 더 낮은 수준의 세부 정보에 액세스할 수 있습니다. 버킷에 새 콘텐츠를 업로드하려면:
Blob blob = bucket.blobBuilder().name("index2.html").
payload("<html><body>hello world2</body></html>").
contentType("text/html").calculateMD5().build();
API를 사용하면 생성 요청에서 다양한 페이로드를 설정할 수도 있습니다.
Blob Map API를 통해 기본 HTML 파일을 S3에 업로드하기 위한 간단한 통합 테스트:
@Test
public void whenFileIsUploadedToS3WithBlobMap_thenNoExceptions() throws IOException {
BlobStoreContext context =
ContextBuilder.newBuilder("aws-s3").credentials(identity, credentials)
.buildView(AWSS3BlobStoreContext.class);
BlobMap bucket = context.createBlobMap("bucketName");
Blob blob = bucket.blobBuilder().name("index2.html").
payload("<html><body>hello world2</body></html>").
contentType("text/html").calculateMD5().build();
bucket.put(blob.getMetadata().getName(), blob);
context.close();
}
2.3. BlobStore 를 통해 업로드
이전 API에는 멀티파트 업로드 를 사용하여 콘텐츠를 업로드할 수 있는 방법이 없었 습니다. 따라서 대용량 파일 작업에 적합하지 않습니다. 이 제한은 우리가 살펴볼 다음 API인 동기 BlobStore API에 의해 해결됩니다.
이것은 컨텍스트에서 얻습니다.
BlobStore blobStore = context.getBlobStore();
멀티파트 지원을 사용하고 파일을 S3에 업로드하려면:
Blob blob = blobStore.blobBuilder("index3.html").
payload("<html><body>hello world3</body></html>").contentType("text/html").build();
blobStore.putBlob("bucketName", blob, PutOptions.Builder.multipart());
페이로드 빌더는 BlobMap API에서 사용하던 것과 동일하므로 여기에서 Blob에 대한 하위 수준 메타데이터 정보를 지정할 때와 동일한 유연성을 사용할 수 있습니다. 차이점은 API의 PUT 작업, 즉 멀티파트 지원 에서 지원하는 PutOptions 입니다.
이제 이전 통합 테스트에서 멀티파트가 활성화되었습니다.
@Test
public void whenFileIsUploadedToS3WithBlobStore_thenNoExceptions() {
BlobStoreContext context =
ContextBuilder.newBuilder("aws-s3").credentials(identity, credentials)
.buildView(AWSS3BlobStoreContext.class);
BlobStore blobStore = context.getBlobStore();
Blob blob = blobStore.blobBuilder("index3.html").
payload("<html><body>hello world3</body></html>").contentType("text/html").build();
blobStore.putBlob("bucketName", blob, PutOptions.Builder.multipart());
context.close();
}
2.4. AsyncBlobStore 를 통해 업로드
이전 BlobStore API는 동기식이었지만 BlobStore 용 비동기식 API 인 AsyncBlobStore 도 있습니다. API는 컨텍스트에서 유사하게 얻습니다.
AsyncBlobStore blobStore = context.getAsyncBlobStore();
둘 사이의 유일한 차이점은 비동기 API가 PUT 비동기 작업 에 대해 ListenableFuture 를 반환한다는 것입니다 .
Blob blob = blobStore.blobBuilder("index4.html").
.payload("<html><body>hello world4</body></html>").build();
blobStore.putBlob("bucketName", blob)<strong>.get()</strong>;
이 작업을 표시하는 통합 테스트는 동기 테스트와 유사합니다.
@Test
public void whenFileIsUploadedToS3WithBlobStore_thenNoExceptions() {
BlobStoreContext context =
ContextBuilder.newBuilder("aws-s3").credentials(identity, credentials)
.buildView(AWSS3BlobStoreContext.class);
BlobStore blobStore = context.getBlobStore();
Blob blob = blobStore.blobBuilder("index4.html").
payload("<html><body>hello world4</body></html>").contentType("text/html").build();
Future<String> putOp = blobStore.putBlob("bucketName", blob, PutOptions.Builder.multipart());
putOp.get();
context.close();
}
3. 결론
이 기사에서는 jclouds 라이브러리가 Amazon S3에 콘텐츠를 업로드하기 위해 제공하는 4가지 API 를 분석했습니다. 이 네 가지 API는 일반적 이며 Microsoft Azure Storage와 같은 다른 키-값 스토리지 서비스와도 함께 작동합니다.
다음 기사에서는 jclouds에서 사용할 수 있는 Amazon 특정 S3 API인 AWSS3Client 를 살펴 보겠습니다 . 대용량 파일을 업로드하는 작업을 구현하고 주어진 파일에 대한 최적의 부품 수를 동적으로 계산하고 모든 부품의 업로드를 병렬로 수행합니다.