0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Azure Blob StorageにSpring Bootでアクセスしてみる

Last updated at Posted at 2021-07-22

諸事情でAzureのBlob Storageへアップロードおよびダウンロードを行う方法を調べる機会があったので、少しメモっておきます。

検証バージョン

  • Spring Boot 2.5.2
  • Azure Spring Boot 3.6.0
  • Azure Storage Blob(Azure JDK for Java) 12.12.0

試したこと

以下の3つの方法でアップロード/ダウンロードが行えることを確認しました。

  • Springの Resource インタフェース経由でアクセスする方法
  • DIコンテナから BlobServiceClientBuilder を取得してAzure JDKのAPI経由でアクセスする方法
  • DIコンテナは使わずに Azure JDK のAPI経由でアクセスする方法

Springの Resource インタフェースの利用

Azure Spring Bootを利用すると、Spring の Resource インタフェース経由でアップロード及びダウンロードを行うことができます。

src/main/resources/application.yml
azure:
  storage:
    account-name: kazuki43zoostorage
    # アカウントキーは環境変数から取得
    #account-key: ${AZURE_STORAGE_ACCOUNT_KEY}
    blob-endpoint: https://${azure.storage.account-name}.blob.core.windows.net
~/.bashrc
export AZURE_STORAGE_ACCOUNT_KEY=xxxxxxxxxxx
@Value("azure-blob://test-container/data/uploadAndDownloadWithResource.txt")
Resource sampleText;

@Test
void uploadAndDownloadWithResource() throws IOException {
  // Upload
  String content = "uploadAndDownloadWithResource";
  try (OutputStream out = ((WritableResource) sampleText).getOutputStream()) {
    out.write(content.getBytes(StandardCharsets.UTF_8));
  }

  // Download
  try (InputStream in = sampleText.getInputStream()) {
    Assertions.assertThat(StreamUtils.copyToString(in, StandardCharsets.UTF_8)).isEqualTo(content);
  }
}

DIコンテナに登録される BlobServiceClientBuilder を利用

Azure Spring Bootを利用すると、Azure Blobに接続するためのコンポーネント(BlobServiceClientBuilder)をDIコンテナから取得し、Azure JDKのAPIを呼び出すことでアップロード及びダウンロードを行うことができます。

SpringのResourceインタフェースを利用すると非常に簡単にアクセスすることができる一方で、Auzre JDKでサポートされている機能をフルに利用できないというデメリットもあります。そのため、Auzre JDKが提供している機能をフルに活用したい場合は、BlobServiceClientBuilderをDIコンテナから取得する方法を利用すると良いと思います。

@Autowired
BlobServiceClientBuilder blobServiceClientBuilder;

@Test
void uploadAndDownloadWithClientOnDIContainer() {
  // Build client
  BlobClient blobClient = blobServiceClientBuilder.buildClient()
      .getBlobContainerClient("test-container")
      .getBlobClient("data/uploadAndDownloadWithClientOnDIContainer.txt");

  // Upload
  String content = "uploadAndDownloadWithClientOnDIContainer";
  {
    BinaryData uploadData = BinaryData.fromString(content);
    blobClient.uploadWithResponse(
        new BlobParallelUploadOptions(uploadData).setComputeMd5(true), Duration.ofSeconds(10), Context.NONE);
  }

  // Download
  {
    BlobDownloadContentResponse downloadResponse = blobClient.downloadContentWithResponse(
        null, null, Duration.ofSeconds(10), Context.NONE);

    String contentMd5 = encoder.encodeToString(DigestUtils.md5Digest(downloadResponse.getValue().toBytes()));
    String headerMd5 = encoder.encodeToString(downloadResponse.getDeserializedHeaders().getContentMd5());
    Assertions.assertThat(contentMd5).isEqualTo(headerMd5);
    Assertions.assertThat(downloadResponse.getValue().toString()).isEqualTo(content);
  }
}

MD5ハッシュ値を利用したアップロードとダウンロードの検証については、Azure SDK側でどこまで行ってくれるのかちゃんとわかってないです・・・・。
BlobParallelUploadOptionsのsetComputeMd5メソッドのJavaDocには「Whether or not the library should calculate the md5 and send it for the service to verify.」と記載があるので、setComputeMd5(true)を指定することで、アップロード時にサーバ側でアップロードしたファイルの検証してくれるのかな〜と思っていますが・・・実際のところよくわかってないです。
ダウンロード時の検証については、おそらくAzure SDKの中で自動で検証してくれる機能はないのかな〜と思っており、Azure SDKのAPI経由でサーバで管理しているコンテンツのMD5ハッシュ値を取得して、実際にダウンロードしたファイルとの検証を自前で行う必要があるのかな〜と思っています(こちらもよくわかってない・・・)。

Azure JDKのAPIだけを利用

Azure JDKのAPIのみを利用してアップロード及びダウンロードを行うことも当然できます。

@Test
void uploadAndDownloadWithClient() {
  String accountName = "kazuki43zoostorage";
  String accountKey = System.getenv("AZURE_STORAGE_ACCOUNT_KEY"); // アカウントキーは環境変数から取得
  // Build client
  BlobClient blobClient = new BlobServiceClientBuilder()
      .endpoint("https://" + accountName + ".blob.core.windows.net")
      .credential(new StorageSharedKeyCredential(accountName, accountKey))
      .buildClient()
      .getBlobContainerClient("test-container")
      .getBlobClient("data/uploadAndDownloadWithClient.txt");

  // Upload
  String content = "uploadAndDownloadWithClient";
  {
    BinaryData uploadData = BinaryData.fromString(content);
    blobClient.uploadWithResponse(
        new BlobParallelUploadOptions(uploadData).setComputeMd5(true), Duration.ofSeconds(10), Context.NONE);
  }

  // Download
  {
    BlobDownloadContentResponse downloadResponse = blobClient.downloadContentWithResponse(
        null, null, Duration.ofSeconds(10), Context.NONE);

    String contentMd5 = encoder.encodeToString(DigestUtils.md5Digest(downloadResponse.getValue().toBytes()));
    String headerMd5 = encoder.encodeToString(downloadResponse.getDeserializedHeaders().getContentMd5());
    Assertions.assertThat(contentMd5).isEqualTo(headerMd5);
    Assertions.assertThat(downloadResponse.getValue().toString()).isEqualTo(content);
  }
}

実行結果

こんな感じでアップロードされました。

image.png

検証アプリ

まとめ

MD5検証がライブラリ側(サーバ側)でどこまで対応しているのかがまだ不明な点はありますが、コンテンツのアップロードおよびダウンロードができることは確認できたので、いったん満足しています。MD5検証どこまでサポートされているか知っている方がいたら是非コメントください!!

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?