jcloudsライブラリを使用してS3にアップロードする
Javaの世界でコンテンツをS3バケットにアップロードするには、いくつかの良い方法があります。この記事では、jcloudsライブラリがこの目的のために提供するものを見ていきます。
jclouds –特にこの記事で説明されているAPIを使用するには、この単純なMaven依存関係をプロジェクトのpomに追加する必要があります。
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-allblobstore</artifactId>
<version>1.5.10</version>
</dependency>
1. AmazonS3へのアップロード
これらの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つのS3API
jcloudsライブラリは、コンテンツをS3バケットにアップロードするための4つの異なるAPIを提供します。これらは、単純だが柔軟性がないものから複雑で強力なものまで、すべてBlobStoreContextを介して取得されます。 最も単純なものから始めましょう。
2.1. MapAPIを介してアップロード
jcloudsを使用してS3バケットを操作する最も簡単な方法は、そのバケットをマップとして表すことです。 APIはコンテキストから取得されます。
InputStreamMap bucket = context.createInputStreamMap("bucketName");
次に、単純なHTMLファイルをアップロードするには:
bucket.putString("index1.html", "<html><body>hello world1</body></html>");
InputStreamMap APIは、他のいくつかのタイプのPUT操作(ファイル、rawバイト)をシングルとバルクの両方で公開します。
簡単な統合テストを例として使用できます。
@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経由でアップロード
単純なMapAPIの使用は簡単ですが、最終的には制限されます。たとえば、アップロードされるコンテンツに関するメタデータを渡す方法はありません。 より柔軟性とカスタマイズが必要な場合、マップを介してS3にデータをアップロードするためのこの単純化されたアプローチではもはや十分ではありません。
次に説明するAPIはBlobMapAPIです。これは、コンテキストから取得されます。
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 MapAPIを介して基本的な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である同期BlobStoreAPIによって対処されます。
これはコンテキストから取得されます。
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経由でアップロード
以前のBlobStoreAPIは同期でしたが、 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ライブラリがAmazonS3にコンテンツをアップロードするために提供する4つのAPIを分析しました。 これらの4つのAPIはgenericであり、MicrosoftAzureStorageなどの他のKey-Valueストレージサービスでも機能します。
次の記事では、jcloudsで利用可能なAmazon固有のS3 API – AWSS3Clientについて説明します。 大きなファイルをアップロードする操作を実装し、任意のファイルの最適なパーツ数を動的に計算し、すべてのパーツのアップロードを並行して実行します。