LoginSignup
2
1

More than 1 year has passed since last update.

Java on Azure 実践開発【Blob Upload ①: ストリームライクなアップロード編】

Last updated at Posted at 2022-05-25

はじめに

本記事は、『Java on Azure 実践開発 Blob Upload』シリーズの第1回「ストリームライクなアップロード」編です。
サンプルコードは、kohei3110/JavaOnAzure-BlobStorage に上がっています。

シナリオ概説

本シリーズでは、Blob Storage へのファイルアップロードについて、Azure を使った Java アプリケーションのサンプルコードを使用しながら、開発方法をご紹介します。

一口にファイルアップロードといっても、あらゆる方式があるかと思います。例えば、以下のようなものがあります。

No. シナリオ 概要 記事 URL
1 サーバー経由でのストリームライクなアップロード SAS の流出を懸念する場合、サーバー経由でのストリームライクなアップロード Java on Azure 実践開発【Blob Upload ①: ストリームライクなアップロード編】
2 サーバーに一時保存後アップロード アプリケーションサーバーのローカルストレージにファイルを一度保存後、アップロード(クライアントからは同期に見える) Java on Azure 実践開発【Blob Upload ②: App Service ローカル保存後アップロード編】
3 サーバーに一時保存後定期アップロード アプリケーションサーバーのローカルストレージにファイルを一度保存後、定期ジョブにてアップロード(クライアントからは非同期に見える) Java on Azure 実践開発【Blob Upload ③: 定期アップロード編】
4 署名付き URL を使ったアップロード アプリケーションから返却された署名付き URL を用いて、クライアントからファイルをアップロードする Java on Azure 実践開発【Blob Upload ④: 署名付き URL を使ったアップロード編】

本記事では、『1. ストリームライクなアップロード』について実装上のポイントを解説していきます。

実装内容

Blob Storage へファイルをストリームライクにアップロードします。想定されるシナリオは、動画などの大きなファイルを、アプリケーション実行環境のローカルファイルストレージには保存せず、直接 Blob ストレージへアップロードする場合などです。

image.png

実装に必要な SDK のクラス

実装にあたって、Azure SDK for Java を使用しました。SDK を使うため、私の方でいくつかクラスを作りました。以下は、その UML 図です。

image.png

ここからは、実装する際に必要となる SDK のクラスについて解説していきます。

BlobAsyncClient クラス

BlobAsyncClient クラスは、Blob Storage の各オブジェクト(Blob)操作をするためのクライアントを提供します。BlobAsyncClient クラスにより、Blob アップロードやダウンロード、Blob のコピーなどの操作が可能になります。

BlobAsyncClient は、BlobClientBuilder でインスタンス化するか、getBlobAsyncClient()メソッドで取得することができます。

なお、Azure では以下3種類の Blob をサポートしています。今回は、ファイルアップロード用途なので、ブロック Blob を使用しました。
これらに対応するクライアントも、Azure SDK for Java で用意されています。

Blob 種類 概要 クライアント取得メソッド Javadoc
ブロック BLOB 大量のデータを効率的にアップロードするためのに最適。 BlobAsyncClient.getBlockBlobAsyncClient Method getBlockBlobAsyncClient()
追加 BLOB 追加操作(仮想マシンのデータのログ記録などのシナリオ)に最適。 BlobAsyncClient.getAppendBlobAsyncClient Method getAppendBlobAsyncClient()
ページ BLOB ランダムな読み取りと書き込みの操作用に最適。 BlobAsyncClient.getPageBlobAsyncClient Method getPageBlobAsyncClient()

参考: 『BlobAsyncClient Class
JavaDoc: 『Class BlobAsyncClient

UploadBlobStreamRepository.java
・・・
            BlobAsyncClient blobAsyncClient = new BlobClientBuilder()
                .connectionString(connectionString)
                .containerName(CONTAINER_NAME)
                .blobName(blobName)
                .buildAsyncClient();
・・・

BlobOutputStream クラス

BlobOutputStream クラスは、データをBlobにストリームライクにアップロードするためのクラスです。

UploadBlobStreamRepository.java
・・・
        BlobOutputStream blobOutputStream = BlobOutputStream.blockBlobOutputStream(
            blobAsyncClient,   // Blob クライアント
            options,   // 並列処理オプション(ParallelTransferOptions)
            headers,   // Blob HTTP ヘッダー
            null,   // Blob に関連付けるメタデータ
            AccessTier.HOT,    // Blob のアクセス層
            new BlobRequestConditions(),   // リクエスト成功時のオプションを指定(指定例は、本記事にて後述)(BlobRequestConditions)
            null  // 追加コンテキスト(key-value ペア)
        );
・・・

ParallelTransferOptions クラス

ParallelTransferOptions クラスは、データ転送処理を並列化するための設定を定義します。

UploadBlobStreamRepository.java
・・・
        ParallelTransferOptions options = new ParallelTransferOptions()
            .setBlockSizeLong((long) (2 * 1024 * 1024))  // blockSize
            .setMaxConcurrency(2)
            .setProgressReceiver(new ProgressReceiver() {

                @Override
                public void reportProgress(long bytesTransferred) {
                    logger.info("uploaded: " + bytesTransferred);
                }
                
            });
・・・

Tips

ここからは、実装上の Tips をご紹介します。

ファイルアップロードの進捗状況を確認する

ProgressReceiver クラスを利用することで、ファイル転送の進捗状況を確認することができます。内部的には、転送された総バイト数とともに reportProgress() メソッドが定期的に呼び出されます。実装時は、このreportProgress() メソッドをオーバーライドすることで、任意の形式で進捗状況を確認することができます。

今回は、進捗状況をログに標準出力する形としました。

UploadBlobStreamRepository.java

・・・
        ParallelTransferOptions options = new ParallelTransferOptions()
            .setBlockSizeLong((long) (2 * 1024 * 1024))  // blockSize
            .setMaxConcurrency(2)
            .setProgressReceiver(new ProgressReceiver() {

                @Override
                public void reportProgress(long bytesTransferred) {
                    logger.info("uploaded: " + bytesTransferred);
                }
                
            }

・・・

出力されるログは以下のようになります。

・・・
2022-05-25 13:40:14.729  INFO 28556 --- [ctor-http-nio-1] c.k.j.U.r.UploadBlobStreamRepository     : uploaded: 567
2022-05-25 13:40:14.729  INFO 28556 --- [ctor-http-nio-1] c.k.j.U.r.UploadBlobStreamRepository     : uploaded: 568
2022-05-25 13:40:14.730  INFO 28556 --- [ctor-http-nio-1] c.k.j.U.r.UploadBlobStreamRepository     : uploaded: 569
2022-05-25 13:40:14.731  INFO 28556 --- [ctor-http-nio-1] c.k.j.U.r.UploadBlobStreamRepository     : uploaded: 570
2022-05-25 13:40:14.731  INFO 28556 --- [ctor-http-nio-1] c.k.j.U.r.UploadBlobStreamRepository     : uploaded: 571
・・・

おわりに

本記事は、『Java on Azure 実践開発 Blob Upload 編】①』として、ストリームライクなアップロードについてまとめました。

次回は、アプリケーションサーバーのローカルストレージにファイルを一度保存後、アップロードする方法についてまとめていきます!お楽しみに~。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1