Cloud Foundryの中の1つ、Pivotal Web Services(PWS)でMySQLの利用

Pivotal Web Services にデプロイしたプロジェクトで利用していたデータベースをH2からMySQLに変更してみたいと思います。

まずは、停止していたプロジェクトを起動するところからですかね、それでははじめていきたいと思います。

Pivotal Web Servicesでプロジェクト起動

Pivotalにログインして、Pivotal Web Servicesを選択。

f:id:ts0818:20171028214255j:plain

「development」の「Apps」でプロジェクト名をクリックします。

f:id:ts0818:20171028214404j:plain

ダッシュボードから起動しても良いのですが、

f:id:ts0818:20171028214539j:plain

Cloud Foundry Command Line Interface (cf CLI)をインストールしてるので、コマンドプロンプトで起動してみます。

cf start [PWSにあるプロジェクト名]

f:id:ts0818:20171028214806j:plain

「Events」に『Started app』って追加されていればOK。

f:id:ts0818:20171028215724j:plain

PWSでMySQLの利用

※ローカル環境に本番環境と同じ環境のバックアップがあることを確認してください。

f:id:ts0818:20171029095557p:plain

いまのところ、本番環境のバックアップの方法が分からないので、ローカル環境に本番環境と同じ環境のものを用意しておく感じで。

 

PWSで利用できるバックエンド・サービスの一覧を確認。

cf marketplace

f:id:ts0818:20171028223245j:plain

※プラン名の右に*が付いているものは有料のようです。

今回は、「cleardb」の「spark」を利用。

cf create-service [サービス名] [プラン名] [サービス・インスタンス名]

⇧ コマンドでサービス・インスタンスを作成します。今回はMySQLサービス・インスタンスを作成。

cf bind-service [アプリケーション名] [サービス・インスタンス名]    

⇧ プロジェクト(アプリケーション)でMySQLサービス・インスタンスを利用する準備

f:id:ts0818:20171028224510j:plain

「cf restage [アプリケーション名]」しろ~、とあるので実行。

cf restage hajiboot-ts0818

f:id:ts0818:20171028230441j:plain

f:id:ts0818:20171028230456j:plain

はい、失敗。

エラーの原因は、DBのマイグレーションツールFlywayで起きたっぽいです。(ローカル環境のSpring Boot のプロジェクトでpom.xmlで「Flyway」を追加しています。)

    2017-10-28T22:55:31.32+0900 [APP/PROC/WEB/0] OUT org.springframework.beans.factory.BeanCreationException:
    Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception
    is org.flywaydb.core.api.FlywayException: Unable to obtain Jdbc connection from DataSource
    
   2017-10-28T22:55:31.32+0900 [APP/PROC/WEB/0] OUT Caused by: org.flywaydb.core.api.FlywayException: Unable to obtain Jdbc connection from DataSource
    
   2017-10-28T22:56:28.25+0900 [APP/PROC/WEB/0] OUT 2017-10-28 13:56:28.253  WARN 14 --- [           main] 
   ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization
   - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException:
   Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.api.FlywayException: Unable to obtain Jdbc connection from DataSource
   
   2017-10-28T22:56:28.28+0900 [APP/PROC/WEB/0] OUT org.springframework.beans.factory.BeanCreationException:
   Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.api.FlywayException: Unable to obtain Jdbc connection from DataSource

.Introduction to Cloud Foundry #JJUG - SSSSLIDE

⇧  「はじめてのSpring Boot 改訂版(著:槙  俊明)」の著者の人のスライドを見て、てっきり「application-cloud.properties」ファイルが自動でできるんかと思ったら、自分で作らないといけないみたいで、尚且つ、ローカル環境で作って再デプロイしないといけないようです。

sshログインで本番環境で作るってのはNG?っぽいのかな~、ちょっと分からんです。

それにしても、本番環境をローカル環境で上書きしていくやり方しかできないとすると、ローカル環境ありきになってしまうのですが、仮にローカル環境を削除してしまっていた場合に本番環境からbackup取れないのは怖いですね。

本番環境のbackupの取得方法が見つからないので、そのへんが気になるのですが...。

 

Spring Bootのプロファイルとは?

「Spring」では「プロファイル」という概念があり、環境ごとに「プロパティ」「Bean定義」などのグループを定義して実行時に切り替えができるようです。開発環境、本番環境といったグループ分けができるようです。

「プロファイル」を使う方法としては、

  1. propertiesファイル、またはyamlファイルにシステムプロパティ『spring.profiles.active』でグループを設定
  2. グループ分のpropertiesまたはyamlファイルを作る
  3. 環境変数「SPRING_PROFILES_ACTIVE」を利用する

の3パターンぐらいあるようです。

 

1.  『spring.profiles.active』でグループを設定

 ・Spring Bootで設定のプロファイル分けをする - Qiita

 

2.   グループ分のpropertiesまたはyamlファイルを作る 

Spring Boot の application.properties (yml) でプロパティが重複したときの挙動 - Qiita

 

3.  環境変数「SPRING_PROFILES_ACTIVE」を利用する

Spring Boot起動時に環境毎にapplication.propertiesを切り替える色々 - Qiita

 

⇧  諸先輩方のサイトが詳しいので参考に。

 

「Cloud Foundry」にSpring Boot のアプリケーションをデプロイした場合、デフォルトで「application-cloud.properties」ファイルを適用してくれるようなので、ローカル環境のSpring Bootのプロジェクトで「application-cloud.properties」ファイルを作成して再度、本番環境にデプロイしていきます。

「application-cloud.properties」ファイル作成と再デプロイ

本番環境がダメになってしまったので、 ローカル環境を再デプロイしていきますが、再デプロイの前に、「application-cloud.properties」ファイルを作成して設定を記述。

いま、「application.properties」ファイルしかないので、

f:id:ts0818:20171029100006j:plain

追加します。フォルダ内の空白部分で右クリックし、「新規作成(X)」>「テキスト ドキュメント」を選択し、

f:id:ts0818:20171029100208j:plain

ファイル名を拡張子も含めて変更していきます。

f:id:ts0818:20171029100939j:plain

「application-cloud.properties」とします。

f:id:ts0818:20171029101036j:plain

拡張子を変更すると出る警告には「はい(Y)」を選択。

f:id:ts0818:20171029101149j:plain

新しくpropertiesファイルができましたので、テキストエディタなどで開いて編集していきます。

f:id:ts0818:20171029101301p:plain

テキストエディタは何でも良いとは思いますが、サクラエディタとかが良さそうですかね。

f:id:ts0818:20171029104852j:plain

ファイルを開きましたら、

f:id:ts0818:20171029102026j:plain

spring.jpa.hibernate.ddl-auto=upload
spring.datasource.initialize=false

を記述して保存。

f:id:ts0818:20171029143526j:plain



ちなみに、今回のプロジェクトは、「はじめてのSpring Boot  改訂版(著:槙 俊明)」という書籍のP.91~の『hajiboot-thymeleaf』プロジェクトを作成して使っています。

f:id:ts0818:20171029104416j:plain

おそらく、拡張子が「.sql」のファイルを

spring.datasource.initialize=false

で無効化していなかったのがで、DBマイグレーションツールのFlywayでエラーが起こってしまっていたってことですかね?

propetiesファイルが準備できたので、新たにプロジェクトのjarを作成するため、「mvnw」ファイルのあるディレクトリを確認します。

f:id:ts0818:20171029110619j:plain

 コマンドプロンプトなどを開いて、ディレクトリを移動し、プロジェクトのjarファイルを作成。

cd C:¥workspace¥hajiboot-thymeleaf
mvnw.cmd clean package -DskipTests=true

f:id:ts0818:20171029111200j:plain

f:id:ts0818:20171029111218j:plain

なぜか、今回は「-DskipTests=true」を付けてもエラーにならず...う~ん、分からん。

「C:¥workspace¥hajiboot-thymeleaf¥target¥hajiboot-thymeleaf-0.0.1-SNAPSHOT.jar」が更新されています。(前回、jarを作っているので更新されたようです。)

f:id:ts0818:20171029111236p:plain

デプロイをしていきますが、「サービス・インスタンス」は、バインド先のアプリケーションのステージング前にバインドされている必要があるらしく、「--no-start」オプションをつけてデプロイする必要があるみたいです。

cf push hajiboot-ts0818 -p target/hajiboot-thymeleaf-0.0.1-SNAPSHOT.jar -b java_buildpack --no-start

f:id:ts0818:20171029112433j:plain

続いて、デプロイしたアプリケーションを「MySQLサービス・インスタンス」にバインドします。

cf bind-service hajiboot-ts0818 ts0818db

f:id:ts0818:20171029112859j:plain

 バインドが成功すると、環境変数「VCAP_SERVICES」に「MySQLサービス・インスタンス」の接続情報が追加されるようです。

「cf env [アプリケーション名]」で確認できるようです。

cf env hajiboot-ts0818

f:id:ts0818:20171029113715j:plain

「VCAP_SERVICES」というJSONの「credentials」というキーの値として「MySQL」の接続情報が 取得できるようです。

 

アプリケーションの起動

「cf start [アプリケーション名]」でアプリケーションを起動

cf start hajiboot-ts0818

f:id:ts0818:20171029115816j:plain

f:id:ts0818:20171029115830j:plain

はい、エラー。 

   2017-10-29T11:45:56.71+0900 [APP/PROC/WEB/0] OUT 2017-10-29 02:45:56.710  WARN 15 --- [           main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.api.FlywayException: Schema `ad_eaced1ce5185007` contains a failed migration to version 3 !

マイグレーションに失敗って...う~ん、Flywayが問題っすか。

mvnw.cmd compile flyway:info

⇧ flywayの状況を確認できるかと思いきや...これまたエラー。

f:id:ts0818:20171029134243j:plain

どうやら、Flywayで「DBマイグレーション」する方法には、

  1. コマンドラインツール(flyway コマンド)
  2. Maven・Gradleなどのプラグイン
  3. Java API

の3つほどあり、Spring Bootで利用してるのは、「3. Java API」らしいです。pom.xmlに 

<dependency>
	<groupId>org.flywaydb</groupId>
	<artifactId>flyway-core</artifactId>
</dependency>

って追記しているから、mavenプラグインかと思っていたのですが、さにあらず!

って...これ、Java APIマイグレーションの状況はどうやって確認すれば?

いろいろ試行錯誤した結果、pom.xmlの「flyway」の部分をコメントアウトして無効化して新たにjarファイルを作成、デプロイ、MySQLサービス・インスタンスにバインド、アプリケーションを起動で動きました。

<!--
<dependency>
	<groupId>org.flywaydb</groupId>
	<artifactId>flyway-core</artifactId>
</dependency>
-->

f:id:ts0818:20171029195712j:plain

f:id:ts0818:20171029144127j:plain

f:id:ts0818:20171029144144j:plain 

f:id:ts0818:20171029165657j:plain

f:id:ts0818:20171029165717j:plain

f:id:ts0818:20171029170036j:plain

根本的な解決にはなってないですが、動きました!

f:id:ts0818:20171029170819j:plain

ブラウザでアクセスしてみます。「http://アプリケーション名..cfapps.io」でアクセスできます。

f:id:ts0818:20171029170902j:plain

顧客を追加してみます。 

f:id:ts0818:20171029170918j:plain

「Dora Emon」さんが追加されました。 

f:id:ts0818:20171029170939j:plain

ただ、実際にMySQLのテーブルとかを確認できていないのですが、

Cloudn PaaS v2(CloudFoundry)の Service(PostgreSQL & MySQL)に接続 - Qiita

日本Cloud Foundryグループ ブログ: phpMyAdminをCloud Foundryで動かして、お手軽DBメンテナンス!

日本Cloud Foundryグループ ブログ: SQL Buddy を Cloud Foundry で動かす

 のサイトを参考に、何かしらのコマンドやツールをインストールしていくしかなさそうです。

 

あんまりメモリを消費しない方法を見極めて、インストールを試みていきたいですね。なんせ、無料枠は2GBまでですから~、残念!

 

利用してないときは忘れずアプリを停止しときましょう。

f:id:ts0818:20171029175348j:plain

f:id:ts0818:20171029175404j:plain

それにしても、無料で使わせてもらっているので文句は言えないですが、Pivotal Web ServicesのCloud Foundry使い勝手があんまり良くない気が...。

今回もハマりにハマりましたが、Flyway込みのデプロイはできずでしたが、MySQLは使えたっぽいということで。