Spring Boot Starter for Azure Storage を使ってみる
自身でもちょっと混乱したので、備忘録代わりの記事です。Spring Boot for Azure Storage で検索すると、以下のサイトがヒットしたりしますが、この spring-starter-azure-storage
ライブラリはすでに Deprecated です。
Azure Storage 用の Spring Boot Starter の使用方法 | Microsoft Docs
最新は名前も変って azure-spring-boot-starter-storage
となってます。現在の最新のライブラリは、基本的に azure-spring-boot-starter
で始まっています(一部古いものもありますが)
使ってみる
このライブラリでは、BlobServiceClientBuilder
を DIする方法と、Value
アノテーションを使って、リソースをDIする方法が提供されています。はじめに、BlobServiceClientBuilder
を DI する方法を試してみましょう。
https://start.spring.io/ からの生成に対応しているので、そちらを使うと便利ですが、pom.xml
の 依存関係には以下が必要です。
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>azure-spring-boot-starter-storage</artifactId>
</dependency>
そして、application.properties
には、 ストレージアカウント名、アカウントキー、エンドポイント名が必要です。
azure.storage.accountName=<<your account name>>
azure.storage.accountKey=<<your account key>>
azure.storage.blob-endpoint=https://<<account name>>.blob.core.windows.net/
コンストラクタインジェクションでも、フィールドインジェクションでもどちらも構いません。以下はコンストラクタインジェクションで試しています。BlobServiceClientBuilder
からクライアントインスタンスをビルドするのですが、同期クラアントでも非同期クライアントでもどちらでもよいでしょう。Sprinb Boot WebFlux は、Project Reactor による非同期プログラミングをサポートしているので、以下では非同期クライアントをビルドしています。Azure Storage SDK for Java 自身が、Reactorによる非同期に対応しているので、相性は良いと思います。
以下は、ザックリとコンテナ一覧を表示している例です。listBlobContainers
して コンテナ名を返しているところです。戻り値が、Mono<List<Strting>>
で、Flux<String>
ではないのは、WebFluxの仕様上の話です。Flux<String>
で返すと、JSONのチャンクとして扱われてしまうようで、少しハマリました。
RestController
public class BlobController {
private final BlobServiceAsyncClient blobServiceAsyncClient;
public BlobController(BlobServiceClientBuilder builder) {
this.blobServiceAsyncClient = builder.buildAsyncClient();
}
@GetMapping(value = "/containers", produces = MediaType.APPLICATION_JSON_VALUE)
public Mono<List<String>> listContainers() {
return this.blobServiceAsyncClient
.listBlobContainers()
.map(c -> c.getName())
.collectList();
}
}
もう1つの Resource
に差し込む方法として、以下のようにValue
アノテーションで、DIすることができます。形式は、azure-blob://コンテナ名/ブロブ名
になります。以下は、プロパティファイルで置換しています。
@Value("azure-blob://${containerName}/${blobName}")
private Resource blobFile;
@GetMapping("/blob")
public String hello() throws IOException {
return StreamUtils.copyToString(
this.blobFile.getInputStream(),
Charset.forName("UTF-8"));
}
ちなみに、blobFile.getInputStream()
を呼ぶと、ライブラリ側でblock()
されているらしく、WebFlux 上では例外が出て動きませでしたので注意が必要です。
イマイチ使いどころが分りませんが、もう少しpring フレームワークを知れば、なにか使いどころがあるのかもしれません。
まとめ
プロパティに、ストレージキーが書かれていますが、Managed IDに対応しているかは、GithubのREADMEには書かれていませんでしたので不明です。時間があれば試してみたいと思います。
あと、サービス毎にストレージ分けたりした場合、複数のアカウントに対応してないっぽいので、それも使いにくいかもしれません。そのあたりのサービスはさくっと実装してもあまり手間がない気もします。