🌟

Azure へデプロイ前 Spring Apps をローカル環境での実行方法

2022/10/13に公開

本記事では、「Azure Spring Apps」のローカル実行について、ご紹介したいと思います。

サービス名は最初「Azure Spring Cloud」となりましたが、2022年5月頃「Azure Spring Apps」と改名されました。

Azure Spring Apps では、コードをほとんど変更せずに、Spring Boot アプリケーションを Azure に簡単にデプロイできます。Spring アプリケーションのインフラストラクチャはこのサービスによって管理されるため、開発者はビジネスロジック・コードに専念できるメリットがございます。
詳しくは公式資料をご覧ください。
https://docs.microsoft.com/ja-jp/azure/spring-apps/overview

Azure Spring Apps アプリケーションを Azure へデプロイする前に、ローカル環境での実行方法について説明します。アプリケーションの依存関係次第で環境構築と実行方法が違います。データベースとキャッシュなどの依存がなければ、普通の Spring Boot アプリケーションとしてローカル環境で実行できます。

これから Azure Cosmos DB と接続する Azure Spring Apps アプリケーションを例としてローカル環境での実行方法を試してみます。

対象アプリ City-service

https://github.com/microsoft/azure-spring-cloud-training/tree/master/06-build-a-reactive-spring-boot-microservice-using-cosmosdb/city-service
依存関係: Cosmos DB と接続し、city という Collection からデータを抽出・表示
プロジェクトコードをローカルへダウンロードします。

ローカル環境

OpenJDK 64-Bit Server VM (build 17.0.2+8-86, mixed mode, sharing)
Apache Maven 3.8.5
OS: Windows10
Git & Git Bash: version 2.35.1.windows.2

設定

1. ローカル環境で DB をセットアップ

ローカル環境から Azure Cosmos DB へ直接接続できないため、Azure Cosmos DB Emulator を利用します。Azure Cosmos DB Emulator は、Azure Cosmos DB サービスを開発目的でエミュレートするローカル環境となります。ローカルでの開発とテストは、Azure のコストをかけずに実施できます。現時点は、Azure Cosmos DB Emulator は Windows、Linux、macOS、および Windows Docker 環境をサポートしています。

1.1 インストール

以下の公式手順の「エミュレーターをインストールする」部分よりインストールを行います。
https://docs.microsoft.com/ja-jp/azure/cosmos-db/local-emulator?tabs=ssl-netstd21

完了後自動的に立ち上がり、Windows タスク バーの通知領域にアイコンが表示されます。
以下の URL より Emulator のデータ エクスプローラーを開きます。
https://localhost:8081/_explorer/index.html

データ エクスプローラーの画面に、 URI と Primary Key の値をメモしておきます。後の設定ファイルに使われます。

1.2 データベース作成

まず、コンテナーの追加を行います。
左側のメニューから「Explorer」へ移動、「 New Container 」をクリックします。
表示された New Container 画面に以下の設定を入力します。
* Database id: spring-apps-cosmosdb002
* Container id: City
* Partition key: /name
最後「OK」ボタンを押下します。

1.3 データ投入

上記作成したデータベースを展開して、item まで表示させます。
次は、「New Item」をクリックします。

Json データーを 2 回分けて右側の入力欄に貼り付けて、「Save」ボタンを押します。
{
"name": "Paris, France"
}

同様で以下のデータを登録します。
{
"name": "London, UK"
}

登録した 2 件のレコードを確認します。

2. アプリケーション設定

ローカル環境実行用の application.proerpties を作成します。
プロジェクト直下の src/main/resources へ移動し、以下の手順を実行します。
touch application-local.properties
vi touch application-local.properties

azure.cosmosdb.uri=上記メモの URI を貼り付け
azure.cosmosdb.key=上記メモの Primary Key 貼り付け
azure.cosmosdb.database= Cosmos DB を設定した際に、New Container 画面に入力した Database id を貼り付け
# Local run は、eureka 機能をオフにする
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
# Local run は、Spring Cloud Config service 機能をオフにする
spring.cloud.config.import-check.enabled=false

3. JDK 設定

Java トラストストアへ認証局証明書をインポートする必要があります。
理由:Cosmos DB の URI は https となっているため、Java は Https のアプリへ接続すると、接続先の認証局証明書はトラストストア($JAVA_HOME/lib/security/cacerts)に存在する必要があります。Java のトラストストアにすでに主なルート認証局の証明書が入っています。もし新規追加しないと、Java はその証明書を信用せず、アプリケーションへの接続に失敗します。エラーの詳細は本記事の補足部分をご参照ください。

3.1 証明書ダウンロード

https://localhost:8081/_explorer/index.html アクセス(Chromeの場合)
まずアドレス欄のロックアイコンをクリックします。ポップアップ画面に「この接続は保護されています」を選択します。

次の画面に「証明書は有効です」を選択します。

表示された画面に「詳細」タブへ切り替え、「選択した証明書をエクスポート」ボタンをクリックします。保存先を設定して、デフォルトの拡張子( Base64 エンコード ASCII 形式の単一の証明書)でファイル名を入力・保存します。保存先のフォルダに出力した crt ファイルを確認します。

Chrome からエクスポートの代わりに、Windows 証明書マネージャーを使用してダウンロードする方法もあります。詳細は公式資料 https://docs.microsoft.com/ja-jp/azure/cosmos-db/local-emulator-export-ssl-certificates ご参照ください。

3.2 証明書をインポート

cd $JAVA_HOME/lib/security/cacerts
keytool -cacerts -importcert -alias cosmos_emulator -file {上記保存した箇所のパス}/{crtファイル名}

次は、パスワード提示の画面が表示されます。「changeit」を入力します。
Enter keystore password:

最後は「この証明書を信頼しますか? 」と聞かれます、「yes」を入れます。
Trust this certificate? [no]: yes
Certificate was added to keystore

Azure Cosmos DB Emulator の Certificate TLS/SSL 証明書がインストールされると、アプリケーションはローカルの Azure Cosmos DB Emulator に接続し、それを使用できるようになります。 問題が発生した場合は、SSL/TLS 接続のデバッグに関する記事を参照してください。https://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/ReadDebug.html

実行

次のコマンドを実行してアプリを起動させます。

cd {プロジェクトフォルダ}
# ビルド
mvn clean package -DskipTests
# ローカル環境で実行
mvn spring-boot:run -Dspring-boot.run.profiles=local

起動後のコンソールは以下の通りです。

動作確認

curl http://localhost:8080/cities またはブラウザで http://localhost:8080/cities へアクセスして、Http Status = 200 & 正常レスポンスを確認します。

$ curl -v  http://localhost:8080/cities
*   Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /cities HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< transfer-encoding: chunked
< Content-Type: application/json
<
[[{"name":"Paris, France"},{"name":"London, UK"}]]* Connection #0 to host localhost left intact

まとめ

上記の手順で Spring Apps をローカル環境実行ができましたが、あくまで単体の機能となります。Configure Server と Eureka などの部分、また Cosmos DB 以外依存する Spring Apps は今後の記事で確認・検証します。

補足:警告・エラー対処

1. ImportException

設定サーバーと関係する設定がない場合のエラーです。上記提示された Action 通りで、もし設定サーバーを使うと、「spring.config.import=configserver: property」を .properties ファイルに定義します、例:spring.config.import=configserver:http://localhost:8888
必須では無ければ、spring.cloud.config.enabled=false or spring.cloud.config.import-check.enabled=false を .properties ファイルに記載します。

2. InstanceInfoReplicatorの警告

Eureka は Netflix 社当初開発したフレームワークです。マイクロサービス構成のシステムに新規配布したサービス検出・登録・管理できる機能を持っています。英訳は「Service Discovery」となります。詳細は公式資料をご参照ください。
https://spring.io/projects/spring-cloud-netflix
本記事のローカル環境は Eureka 部分をカーバーしていないため、上記の手順通りで application-local.properties に Eureka に関する設定を無効にします。 設定しないと、警告が出力されます。

3. sun.security.validator.ValidatorException

Java トラストストアへ認証局証明書をインポートしていない場合、Exception が発生します。上記の手順で解決できます。その他、SSL アクセス用のキーの認証手続きをスキップさせる手もあります、接続用の HttpClient パラメーターをいじって対応可能ですが、今回 Lib を使っているため、適切な選択肢ではないです。詳しくは、以下の記事を参照ください。
https://stackoverflow.com/questions/1828775/how-to-handle-invalid-ssl-certificates-with-apache-httpclient

Discussion