Javaの世界でS3バケットにコンテンツをアップロードするにはいくつかの良い方法があります – この記事ではhttp://www.jclouds.org/[jclouds library]がこの目的のために提供するものを見ていきます。
jclouds、特にこの記事で説明したAPIを使用するには、https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.jclouds%22%20AND%20a%3A%22jclouds-を使用してください。 allblobstore%22[単純な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などの一般的なKey-Valueストレージサービスへのエントリポイントを表しますが、これに限定されません。
より具体的な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バケットにアップロードするための4つの異なるAPIが用意されています。これらのAPIは、単純だが柔軟性がなく、複雑で強力なものまで、すべて
BlobStoreContext
から取得されます。最も簡単なものから始めましょう。
2.1.
Map
API
を介してアップロードする
jcloudsを使ってS3バケットと対話する最も簡単な方法は、そのバケットをMapとして表すことです。 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
hashなど、より低レベルの詳細にアクセスできます。バケットに新しいコンテンツをアップロードする方法
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は
multipart upload
を使ってコンテンツをアップロードする方法がありませんでした – これは大きなファイルを扱うときには不適切になります。この制限は、次回の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
、つまり
multipart support
です。
前回の統合テストでマルチパートが有効になりました。
@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
–
AsyncBlobStore
用の
非同期API
もあります。 APIも同様にコンテキストから取得されます。
AsyncBlobStore blobStore = context.getAsyncBlobStore();
この2つの唯一の違いは、非同期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
を分析しました。これら4つのAPIは
generic
であり、Microsoft Azure Storageなどの他のKey-Valueストレージサービスとも連携します。
次回の記事では、jcloudsで利用可能なAmazon固有のS3 API、つまり
AWSS3Client
について説明します。大きなファイルをアップロードする操作を実装し、特定のファイルに最適な部分数を動的に計算し、すべての部分のアップロードを並行して実行します。