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

について説明します。大きなファイルをアップロードする操作を実装し、特定のファイルに最適な部分数を動的に計算し、すべての部分のアップロードを並行して実行します。