メニューを閉じる

テクノデジタルグループ

メニューを開く

2018.06.21

プログラミング

【Java】CSE&マルチパートアップロードを利用し、S3へファイルをアップロードする

みなさん、こんにちは。
MTです。

最近S3へのアップロードについて調べる機会がありましたので、
自身の復習も兼ねて「S3へのアップロード方法」についてご紹介します。

前提

・アップロードするファイルは事前にファイルサイズが分かっていること。
・サイズが不明な場合は、低レベルAPIを利用します。(今回は高レベルAPIを利用)
・100Mbを超えるような、大容量ファイルを想定。
・マルチパートアップロードを使用する場合、最低でも5MBでなければいけません。
・暗号化アルゴリズムにはAESを指定する。
・なお、暗号化に使用する鍵はこちら側で準備。
⇒KMSを利用する方法もありますが、今回はなし。

準備

暗号鍵ですが、AWS SDKは 256bit の鍵を要求します。
しかし、Javaの場合は128bitがデフォルトの鍵長なので、256bitまで引き上げる必要があります。

下記のサイトから「jce_policy-8.zip」をDL・解凍し、 「US_export_policy.jar」と「local_policy.jar」を「$JAVA_HOME/jre/lib/security」内のファイルと置き換えてください。

・http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

コード

まずはコードから記載します。

// 1. AESで暗号化を行うための準備
final String encryptKey = "1HWO6yJfu3pEEqEBZPhWHIKQIKKE8T6r";
final byte[] keyBytes = encryptKey.getBytes(StandardCharsets.UTF_8);
final SecretKey secretKey = new SecretKeySpec(keyBytes, "AES");
final EncryptionMaterials materials = new EncryptionMaterials(secretKey);

// 2. S3クライアントを作成
final String region = "ap-northeast-1";
final String awsAccessKey = "xxxxxxxxxxxx";
final String awsSecretKey = "yyyyyyyyyyyy";

final AWSCredentialsProvider credentials = new AWSStaticCredentialsProvider(new BasicAWSCredentials(awsAccessKey, awsSecretKey));
final AmazonS3 s3 = AmazonS3EncryptionClientBuilder.standard()
                        .withRegion(region)
                        .withCredentials(credentials)
                        .withEncryptionMaterials(new StaticEncryptionMaterialsProvider(materials))
                        .build();

// 3. アップロード対象となるファイルを取得
final File uploadFile = new File("uploadFile.txt");

// 4. 転送マネージャーを作成
final long threshold = 5L * 1024L * 1024L;
final TransferManager transferManager = TransferManagerBuilder.standard()
                         .withS3Client(s3)
                         .withMultipartUploadThreshold(threshold)
                         .build();

// 5. アップロード
final String bucketName = "my-bucket";
final Upload upload = transferManager.upload(bucketName, uploadFile.getName(), uploadFile);
upload.waitForCompletion();

// 6. 転送マネージャーを終了させる
transferManager.shutdownNow();

順番に何をしているか説明します。

1. AESで暗号化を行うための準備

アップロードファイルの暗号化アルゴリズムにはAESを利用するため、256bitの暗号鍵を用意します。
※勿論記載してある鍵はダミーなので、適時置き換えてください。
最終的には EncryptionMaterials が欲しいデータになります。

2. S3クライアントを作成

アクセスキーやシークレットキー等で、S3を操作するためのクライアントを作成します。
アップロードファイルを暗号化する場合 AmazonS3EncryptionClientBuilder を使用し、
withEncryptionMaterialsメソッドに1で作成したEncryptionMaterials を設定します。

3. アップロード対象となるファイルを取得

今回は File オブジェクトとしてアップロードを行いますが、ストリームをソースとしてアップロードすることも可能です。
※ストリームをソースとする場合、ObjectMetadata というインスタンスが必要となるのですが、
ObjectMetadata#setContentLength メソッドでストリームのサイズを設定してください。
指定しない場合、OutOfMemoryエラーが発生する可能性があります。

4. 転送マネージャーを作成

アップロード機構である TransferManager を TransferManagerBuilder を使用して生成します。
withS3Client メソッドで2で作成したS3クライアントを設定。
withMultipartUploadThreshold でマルチパートアップロードを行う閾値を設定しています。
今回は5MBを閾値として設定していますので、5MBを超えるファイルの場合はマルチパートアップロードでアップロードされます。
⇒なお、デフォルトの閾値は16MBです。

5. アップロード

TransferManager#upload メソッドで、ファイルのアップロードを行います。
TransferManager#uploadFuture のような非同期オブジェクトである Upload を返却します。
アップロードの完了を待ちたい場合には記載コードのように、waitForCompletion メソッドを呼びます。
waitForCompletionはアップロードの完了を待ちますが結果を返さないので、結果が欲しい場合には waitForUploadResult を呼び出してください。

余談ですが、アップロードサイズが大きい場合にはある一定のサイズに分割して並列アップロードされます。
⇒確か、デフォルトだと10スレッドだった気がします。

6. 転送マネージャーを終了させる

アップロードの完了後に、転送マネージャを終了させます。

最後に

如何でしたでしょうか。
今回は高レベルAPIである TransferManager を使用したので楽にアップロード処理が実装できました。
更に細かい制御を行いたい場合は、低レベルAPIを使用することもできるため、アップロード1つとっても学ぶべきことは多いです。
今後、低レベルAPIを使用したアップロードも調査してみたいと思います。


【記事への感想募集中!】

記事への感想・ご意見がありましたら、ぜひフォームからご投稿ください!
  • こんな記事が読んでみたい、こんなことが知りたい、調べてほしい!という意見も募集中!
  • いただいた感想は今後の記事に活かしたいと思います!

感想フォームはこちら


【テクノデジタルではエンジニア/デザイナーを積極採用中です!】

下記項目に1つでも当てはまる方は是非、詳細ページへ!
  • 自分でアプリを作ってみたい
  • ITで世の中にワクワクを生み出したい
  • 使いやすさ、デザインにこだわったWebサイトを開発したい

採用情報の詳細はこちら


Qangaroo(カンガルー)

  • 徹底した見やすさと優れた操作性で、テストの「見える化」を実現。
  • テストの進捗が見える。開発がスマートに進む。
  • クラウド型テスト管理ツール『Qangaroo(カンガルー)』

【テクノデジタルのインフラサービス】

当社では、多数のサービスの開発実績を活かし、
アプリケーションのパフォーマンスを最大限に引き出すインフラ設計・構築を行います。
AWSなどへのクラウド移行、既存インフラの監視・運用保守も承りますので、ぜひご相談ください。
詳細は下記ページをご覧ください。

https://www.tcdigital.jp/infrastructure/

最近の記事