2
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.

セゾン情報システムズAdvent Calendar 2020

Day 13

AzureBlobStorgeSDK for Java + Azurite docker を使ってみた

Last updated at Posted at 2020-12-12

はじめに

この記事は セゾン情報システムズ Advent Calendar 2020 13日目の記事です。
Azuriteは非常に便利なツールなのですが、日本語の情報が殆どないので書きました。

Azuriteとは

Azureのストレージサービスをローカルでエミュレートできるという代物です。AWSのS3でいうminioのようなものですね。
詳しくは公式ドキュメントを参照あれ。

Azurite オープンソース エミュレーターには、Azure Blob およびキュー ストレージ アプリケーションをテストするための無料のローカル環境が用意されています。 ローカルでのアプリケーションの動作に満足できたら、クラウドでの Azure Storage アカウントの使用に切り替えることができます。 エミュレーターは、Windows、Linux、および macOS でのクロスプラットフォーム サポートを提供します。

AzuriteはVSCodeの拡張機能やnpmパッケージ、dockerイメージなどの形で配布されています。
今回はDockerイメージ形式で利用していきます。
また、今回はBlobストレージのエミュレーティングを利用してみます。

参考

SDKの公式クイックスタート - https://docs.microsoft.com/ja-jp/azure/storage/blobs/storage-quickstart-blobs-java
AzuriteのGithub - https://github.com/azure/azurite

環境

  • OS : macOS Catalina 10.15.6
  • Java : AdoptOpenJDK11 14.0.2
  • Docker : 19.03.12
  • AzureSDK : com.azure:azure-storage-blob:12.8.0

Azuriteの起動

まずは公式ドキュメントにある通り、Dockerイメージをプルして起動します。
なお、バックグラウンド実行したいので公式ドキュメントのコマンドに-dを追加しています

$ docker pull mcr.microsoft.com/azure-storage/azurite
Using default tag: latest
latest: Pulling from azure-storage/azurite
cbdbe7a5bc2a: Pull complete
9287919c3a0f: Pull complete
43a47bbd54c9: Pull complete
3c1bcea295c4: Pull complete
5047118b6920: Pull complete
77c92003e19f: Pull complete
13ec4a55a3c3: Pull complete
21145ef27392: Pull complete
db43acfda40e: Pull complete
Digest: sha256:6b6c9c24e97a6c000a81503a41bbf366f04c23aa3b473bfc27267145c92eeceb
Status: Downloaded newer image for mcr.microsoft.com/azure-storage/azurite:latest
mcr.microsoft.com/azure-storage/azurite:latest

$ docker run -d -p 10000:10000 -p 10001:10001 \
    mcr.microsoft.com/azure-storage/azurite
fc6aba0b5929aa2b7fcb9fb7d2b51d2b9e06c31c0d5486cce580798f7e844eef

Azuriteでは、接続文字列は以下の2つになり、どちらでも繋がります。2つ目のほうが本物のAzureBlobストレージに近い形式ですね。

UseDevelopmentStorage=true

もしくは

DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;

Azuriteにデータを作る

本当はDockerの起動時にマウントするなどしてデータを持たせたいのだが、中を見てみると一見して理解できない構造でデータを持っているようで、それができないでいる。
詳しい人いたら教えて下さい。。。

Azure Storage Explorerから作る

Azure Storage ExplorerというツールでGUIからデータを作成できます。

  1. 「Azure Storage へ接続する」で「ローカルエミュレーターにアタッチする」を選択する
    スクリーンショット 2020-09-11 18.15.26.png
    あとはデフォルトで登録
  2. エクスプローラーからContainerを作成する
  3. ファイルをアップロードする
    スクリーンショット 2020-09-11 18.22.26.png

JavaからSDKを使ってアクセスする

クイックスタートに従ってJavaからアクセスしてみます。
build.gradleに依存関係を追加します。

build.gradle
dependencies {
    compile 'com.azure:azure-storage-blob:12.8.0'  // 追加
}

コンテナ名、オブジェクト名、オブジェクトの最終更新日時を表示してみます。

AzureSdkApp.java
import com.azure.core.http.rest.PagedIterable;
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;
import com.azure.storage.blob.models.BlobContainerItem;

public class AzureSdkApp {
    public static void main(String[] args) {
        final BlobServiceClient blobClient = new BlobServiceClientBuilder().connectionString("UseDevelopmentStorage=true").buildClient();
        final PagedIterable<BlobContainerItem> containers = blobClient.listBlobContainers();
        containers.forEach(container -> {
            final String containerName = container.getName();
            System.out.println("containerName = " + containerName);
            final BlobContainerClient containerClient = blobClient.getBlobContainerClient(containerName);
            containerClient.listBlobs().forEach(blob -> {
                final String blobName = blob.getName();
                System.out.println("blobName = " + blobName);
                System.out.println("blob.getProperties().getLastModified() = " + blob.getProperties().getLastModified());
            });
            System.out.println("==========");
        });
    }
}

実行結果(Azuriteにデータを作ってあります)

containerName = container-1
blobName = folder-1/test.txt
blob.getProperties().getLastModified() = 2020-12-12T05:14:36Z
blobName = test.txt
blob.getProperties().getLastModified() = 2020-12-12T05:14:53Z
==========
containerName = container-2
==========

とこんな感じでAzureSDKを使ったプログラムの動作確認環境としても、Azuriteは便利です。
AzureSDKも非常に使いやすいですね。(この記事を書いている最中に、この記事を書くきっかけになったハマリポイントをかんたんに解決する方法が見つかったのは内緒
ぜひ皆さん使ってみてください〜〜

おまけ:Javaからコンテナの起動、オブジェクトの作成もやってみる

上記のコードのテストを書きたくなったときなど、Javaからコンテナの起動・オブジェクトの作成もしたくなる場合があると思います。
そんなときはtestcontainersを使ってJavaからコンテナを操作します。

build.gradleに依存関係を追加します。

build.gradle
dependencies {
    compile 'com.azure:azure-storage-blob:12.8.0'
    compile 'org.testcontainers:testcontainers:1.14.3'  // 追加
}

GenericContainerを継承したAzuriteContainerクラスを作成します。
接続文字列内のBlobEndpointのホスト名がlocalhostになっていることに注意!
127.0.0.1だと繋がりません

AzuriteContainer.java
import org.testcontainers.containers.GenericContainer;

public class AzuriteContainer extends GenericContainer {
    public AzuriteContainer() {
        super("mcr.microsoft.com/azure-storage/azurite");
    }

    @Override
    protected void configure() {
        super.configure();
        addFixedExposedPort(10000, 10000);
    }

    public String getConnectionString() {
        return "DefaultEndpointsProtocol=http;" +
                "AccountName=devstoreaccount1;" +
                "AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;" +
                "BlobEndpoint=http://localhost:10000/devstoreaccount1";
    }
}

テストコード内から起動・オブジェクトの作成をしてみます。

AzureSdkAppTest.java
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;
import com.azure.storage.blob.models.BlobItem;
import com.azure.storage.blob.specialized.BlockBlobClient;
import com.example.azuresdktest.container.AzuriteContainer;
import org.junit.jupiter.api.Test;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;


class AzureSdkAppTest {
    @Test
    void azureTest() throws IOException {
        try(final AzuriteContainer azuriteContainer = new AzuriteContainer()) {
            azuriteContainer.start(); // コンテナの起動

            final BlobServiceClient serviceClient = new BlobServiceClientBuilder().connectionString(azuriteContainer.getConnectionString()).buildClient();
            final String containerName = "test-container";
            serviceClient.createBlobContainer(containerName); // コンテナの作成

            final BlobContainerClient containerClient = serviceClient.getBlobContainerClient(containerName);
            final String blobName = "testFile.txt";
            final BlockBlobClient blobClient = containerClient.getBlobClient(blobName).getBlockBlobClient();
            final String data = "Hello world!";
            InputStream dataStream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
            blobClient.upload(dataStream, data.length()); // ファイルのアップロード
            dataStream.close();

            // verify
            for (BlobItem listBlob : containerClient.listBlobs()) {
                System.out.println(listBlob.getName());
            }
        }
    }
}

実行結果

testFile.txt

上記のコードはGithubのexampleを参考にしました。
私は利用したことはないのですが、SDKでファイルをダウンロードなどもできるようですね。とても便利だ!

2
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
2
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?