Spring リソース抽象化を使用して Cloud Storage 内のファイルにアクセスする

1. 概要

Spring Framework は ResourceLoader 抽象化を提供して、ファイル システム、クラスパス、ウェブなどのさまざまなソースからファイルを簡単に読み書きできます。既知のプロトコル プレフィックスを使用してリソースの URI を指定するだけで済みます。たとえば、ローカル ファイル システム上のファイルにアクセスするには、file:/data/config.yaml のような URI を指定します。

Spring リソース抽象化と gs: プロトコル プレフィックスを使用して、Cloud Storage に保存されたファイルにアクセスする Spring Boot アプリを作成します。

そのためには、Cloud Shell と Cloud SDK gcloud コマンドライン ツールを使用します。

学習内容

  • Cloud Storage Spring Boot スターターの使用方法
  • Spring で Cloud Storage 内のファイルにアクセスする方法
  • Spring の Resource および WritableResource 抽象化の使用方法

必要なもの

  • Google Cloud プロジェクト
  • ブラウザ(Google Chrome など)
  • Linux の標準的なテキスト エディタ(Vim、Emacs、GNU Nano など)を使い慣れていること

この Codelab をどのように使用しますか?

<ph type="x-smartling-placeholder"></ph> 読み取り専用 演習を読み、完了する をご覧ください。

HTML および CSS ウェブアプリの作成経験をどのように評価されますか。

初心者 中級者 上級者

Google Cloud サービスの使用経験はどの程度ありますか?

<ph type="x-smartling-placeholder"></ph> 初心者 中級 上達 をご覧ください。

2. 設定と要件

セルフペース型の環境設定

  1. Cloud Console にログインし、新しいプロジェクトを作成するか、既存のプロジェクトを再利用します(Gmail アカウントまたは G Suite アカウントをお持ちでない場合は、アカウントを作成する必要があります)。

dMbN6g9RawQj_VXCSYpdYncY-DbaRzr2GbnwoV7jFf1u3avxJtmGPmKpMYgiaMH-qu80a_NJ9p2IIXFppYk8x3wyymZXavjglNLJJhuXieCem56H30hwXtd8PvXGpXJO9gEUDu3cZw

ci9Oe6PgnbNuSYlMyvbXF1JdQyiHoEgnhl4PlV_MFagm2ppzhueRkqX4eLjJllZco_2zCp0V0bpTupUSKji9KkQyWqj11pqit1K1faS1V6aFxLGQdkuzGp4rsQTan7F01iePL5DtqQ

8-tA_Lheyo8SscAVKrGii2coplQp2_D1Iosb2ViABY0UUO1A8cimXUu6Wf1R9zJIRExL5OB2j946aIiFtyKTzxDcNnuznmR45vZ2HMoK3o67jxuoUJCAnqvEX6NgPGFjCVNgASc-lg

プロジェクト ID を忘れないようにしてください。プロジェクト ID はすべての Google Cloud プロジェクトを通じて一意の名前にする必要があります(上記の名前はすでに使用されているので使用できません)。以降、このコードラボでは PROJECT_ID と呼びます。

  1. 次に、Google Cloud リソースを使用するために、Cloud Console で課金を有効にする必要があります。

このコードラボを実行しても、費用はほとんどかからないはずです。このチュートリアル以外で請求が発生しないように、リソースのシャットダウン方法を説明する「クリーンアップ」セクションの手順に従うようにしてください。Google Cloud の新規ユーザーは、300 米ドル分の無料トライアル プログラムをご利用いただけます。

Cloud Shell

ここでは、Google Cloud で動作するコマンドライン環境である Cloud Shell を使用します。

Cloud Shell をアクティブにする

  1. Cloud Console で、[Cloud Shell をアクティブにする] H7JlbhKGHITmsxhQIcLwoe5HXZMhDlYue4K-SPszMxUxDjIeWfOHBfxDHYpmLQTzUmQ7Xx8o6OJUlANnQF0iBuUyfp1RzVad_4nCa0Zz5LtwBlUZFXFCWFrmrWZLqg1MkZz2LdgUDQ をクリックします。

zlNW0HehB_AFW1qZ4AyebSQUdWm95n7TbnOr7UVm3j9dFcg6oWApJRlC0jnU1Mvb-IQp-trP1Px8xKNwt6o3pP6fyih947sEhOFI4IRF0W7WZk6hFqZDUGXQQXrw21GuMm2ecHrbzQ

Cloud Shell を起動したことがない場合、その内容を説明する中間画面が(スクロールしなければ見えない範囲に)が表示されます。その場合は、[続行] をクリックします(以後表示されなくなります)。このワンタイム スクリーンは次のようになります。

kEPbNAo_w5C_pi9QvhFwWwky1cX8hr_xEMGWySNIoMCdi-Djx9AQRqWn-__DmEpC7vKgUtl-feTcv-wBxJ8NwzzAp7mY65-fi2LJo4twUoewT1SUjd6Y3h81RG3rKIkqhoVlFR-G7w

Cloud Shell のプロビジョニングと接続に少し時間がかかる程度です。

pTv5mEKzWMWp5VBrg2eGcuRPv9dLInPToS-mohlrqDASyYGWnZ_SwE-MzOWHe76ZdCSmw0kgWogSJv27lrQE8pvA5OD6P1I47nz8vrAdK7yR1NseZKJvcxAZrPb8wRxoqyTpD-gbhA

この仮想マシンには、必要な開発ツールがすべて準備されています。5 GB の永続ホーム ディレクトリが用意されており、Google Cloud で稼働するため、ネットワーク パフォーマンスが充実しており認証もスムーズです。このコードラボでの作業のほとんどは、ブラウザまたは Chromebook から実行できます。

Cloud Shell に接続すると、すでに認証は完了しており、プロジェクトに各自のプロジェクト ID が設定されていることがわかります。

  1. Cloud Shell で次のコマンドを実行して、認証されたことを確認します。
gcloud auth list

コマンド出力

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
gcloud config list project

コマンド出力

[core]
project = <PROJECT_ID>

上記のようになっていない場合は、次のコマンドで設定できます。

gcloud config set project <PROJECT_ID>

コマンド出力

Updated property [core/project].

3. Cloud Storage にファイルを作成する

Cloud Shell が起動したら、ファイルの作成と Cloud Storage への転送を開始できます。

my-file.txt という名前のファイルを作成します。

$ echo "Hello World from GCS" > my-file.txt

次に、Cloud Storage に新しい一意のバケットを作成し、gsutil を使用してファイルを転送します。

$ BUCKET=spring-bucket-$USER
$ gsutil makebucket gs://$BUCKET
$ gsutil copy my-file.txt gs://$BUCKET

Cloud Storage のストレージ ブラウザに移動し、バケットとファイルがあることを確認します。

4. Spring Boot アプリを初期化する

コマンドラインを使用してアプリの作成を開始し、Spring Initializr で新しい Spring Boot アプリを生成します。

$ curl https://start.spring.io/starter.tgz \
  -d type=maven-project \
  -d dependencies=web,cloud-gcp-storage -d baseDir=spring-gcs | tar -xzvf -

Initializr は、テンプレート アプリの pom.xml の依存関係に spring-boot-starter-webspring-cloud-gcp-starter-storage を自動的に追加します。

テンプレート アプリのディレクトリに移動します。

$ cd spring-gcs

JAVA_HOME が正しい JDK バージョンに設定されていることを確認します。

$ export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64/

Maven を使用してアプリをビルドして実行します。

$ ./mvnw spring-boot:run

ポート 8080 でリッスンが開始されます。新しい Cloud Shell タブを開き、curl を実行してアプリにアクセスします。

$ curl localhost:8080

アプリはまだ有用な処理を行っていないため、404 レスポンスが返されます。

アプリが実行されている Cloud Shell のタブに戻り、Control+C(Macintosh では Command+C)を使用してアプリを強制終了します。

5. Cloud Storage 内のファイルを読み取る

Spring Boot アプリを変更して、my-file.txt(以前に Cloud Storage に保存したファイル)にアクセスするようにします。目標は、HTTP でファイルの内容を単純に返すことです。

以下の手順では、Vim を使用してファイルを編集しますが、Emacs、GNU Nano、または Cloud Shell に組み込まれたコードエディタを使用することもできます。

cloud-editor.png

$ cd ~/spring-gcs

REST コントローラ GcsController をアプリに追加します。

$ vi src/main/java/com/example/demo/GcsController.java

次のコードを貼り付けてください。先ほど作成したバケットのリソース URI は必ず修正します。バケットを確認するには、echo $BUCKET コマンドを実行します。

src/main/java/com/example/demo/GcsController.java

package com.example.demo;

import java.io.IOException;
import java.nio.charset.Charset;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GcsController {

  @Value("gs://REPLACE_WITH_YOUR_BUCKET/my-file.txt")
  private Resource gcsFile;

  @GetMapping("/")
  public String readGcsFile() throws IOException {
    return StreamUtils.copyToString(
        gcsFile.getInputStream(),
        Charset.defaultCharset());
  }
}

Maven でアプリをビルドして実行します。

$ ./mvnw spring-boot:run

アプリがポート 8080 をリッスンします。新しい Cloud Shell タブを開き、curl を実行してアプリにアクセスします。

$ curl localhost:8080

アプリからファイルの内容が返されているはずです。アプリが実行されている前の Cloud Shell タブに移動し、Control+C(Macintosh では Command+C)を使用してアプリを終了します。

6. Cloud Storage 内のファイルに書き込む

Cloud Storage 内のファイルのコンテンツを読み取り、Spring REST コントローラで公開しました。次に、新しいファイルの内容を同じ HTTP エンドポイントに送信して、ファイルの内容を変更します。

HTTP POST に応答し、データを Cloud Storage 内のファイルに書き込む別のメソッドを GcsController に追加する必要があります。今回は、Spring の ResourceWritableResource にキャストします。

必要なインポートを追加して GcsController を更新します。

src/main/java/com/example/demo/GcsController.java

import java.io.OutputStream;
import org.springframework.core.io.WritableResource;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.PostMapping;

新しいエンドポイント メソッドをコントローラに追加します。

src/main/java/com/example/demo/GcsController.java

@RestController
public class GcsController {

  @PostMapping("/")
  String writeGcs(@RequestBody String data) throws IOException {
    try (OutputStream os = ((WritableResource) gcsFile).getOutputStream()) {
      os.write(data.getBytes());
    }
    return "file was updated\n";
  }
  ...
}

Maven でアプリをビルドして実行します。

$ ./mvnw spring-boot:run

アプリがポート 8080 をリッスンします。新しい Cloud Shell タブを開き、curl を実行してアプリにメッセージを投稿します。

$ curl -d 'new message' -H 'Content-Type: text/plain' localhost:8080

ファイルの内容が更新されたことを示す確認メッセージが表示されます。ただし、これを確認するには GET を実行します。

$ curl localhost:8080

アプリから返されたファイルの内容が更新されているはずです。アプリが実行されている Cloud Shell のタブに戻り、Control+C(Macintosh では Command+C)を使用してアプリを強制終了します。

7. 完了

Spring Resource Abstraction を使用して Cloud Storage 内のファイルに簡単にアクセスする方法を学びました。Cloud Storage 内のファイルの読み取りと書き込みが可能な Spring Boot ウェブアプリを作成しました。また、この機能を可能にする Cloud Storage の Spring Boot スターターについても学びました。

詳細

ライセンス

この作業はクリエイティブ・コモンズの表示 2.0 汎用ライセンスにより使用許諾されています。