LastaFluteの環境切り替え

環境ごとに設定を切り替えるための構成が用意されています。

環境切り替え用のproperties

ファイル単位で切り替えるため、一つのファイルで環境ごとのものと環境で変わらないものが混在していると重複の原因になります。 なので、なんでもかんでも切り替えるのではなく、環境切り替え用のpropertiesを用意しています。

デフォルトでは、commonと各アプリにそれぞれ xxx_env.properties が用意されています。 こちらに、DBの接続情報や、メールサーバーの情報などを入れて切り替えるとよいでしょう。

e.g. リファレンス実装のMaihamaプロジェクトでの環境ごとのProperties @Directory
maihama-common
 |-src/main/resources
 |  |-maihama_config.properties // 環境依存しないコンフィグ
 |  |-maihama_env.properties // 環境依存コンフィグ
 |  |-maihama_env_integration.properties // 結合用の環境依存コンフィグ
 |  |-maihama_env_production.properties // 本番用の環境依存コンフィグ

こちらの properties は、プログラム上でタイプセーフに get することができます。

プログラム上で環境切り替え分岐

基本的に、プロパティ値の切り替えだけで環境切り替えを実現するのが理想です。プログラム上で "ローカルだから本番だから" という分岐を入れるのは、あまりオススメではありません。

ですが、どうしてもというときにある程度できるようにしています。

e.g. isDevelopmentHere()による分岐 @Java
if (maihamaConfig.isDevelopmentHere()) { // 開発環境(ローカル)だったら
    ...
}

もしくは、EnvDispatchアノテーションで Logic をまるごと切り替えます。

e.g. EnvDispatchによるロジックの切り替え @Java
@EnvDispatch(dev = SeaLogicDev.class, real = SeaLogicReal.class)
public interface SeaLogic {
    ...
}
// SeaLogicDev と SeaLogicReal は SeaLogic インターフェースをimplements

結合と本番でプログラムを分岐させる方法はデフォルトでは用意していません。 結合はできるだけ本番に近いプログラムで動いて欲しいものだからです。プロパティの値だけで切り替えたいところです。 ですが、どうしてもというときは、isDevelopmentHere()の仕組みを応用すれば、できなくはないので必要になったら修正を。

LastaEnv での環境切り替え

LastaFluteのデフォルトは、LastaEnv 方式です。(Exampleもそうなっています)

こちらの方式であれば、環境依存しないwarファイル が作れます。

System Property で lasta.env

Java の System Property に、lasta.env というキーで環境キーワードを指定します。

例えば、lasta.env=production であれば、maihama_env.properties ではなく、maihama_env_production.properties が読まれます。

_env.properties 以外の properties や Di xml は切り替え対象になりませんので、環境依存のものはすべて _env に集約します。(これは LastaEnv 方式に限らず、そのようにするのが推奨ポリシー)

Javaコマンドの引数にて

なので、組み込みwarで実行するときは、javaコマンドの引数で指定します。

e.g. 本番環境(production)としてアプリを実行 @Command
java -Dlasta.env=production -jar maihama-dockside.war

もし、インストール済みの Tomcat にwarファイルを展開するのであれば、Tomcat側でのJavaコマンド引数に lasta.env を追加します。

logback.xml も env を読む

Exampleでは、logback.xml の中で _env.properties を読んでいます。

できる限り、_env.properties に集約して、環境ごとにファイルをまるごと切り替えるというのがないようにします。 LastaEnv方式で、シンプルさをキープしていく方がよいでしょう。

Maven での環境切り替え

(推奨ではありませんが) Maven の profile 機能を使って切り替えることもできます。

profileごとのresources

src/main/resources
ローカル用 (デフォルト) (環境切り替えがなければこれ)
src/allpackage/resources
パッケージングするすべての環境用 (次に優先)
src/integration/resources
結合環境用 (最優先)
src/production/resources
本番環境用 (最優先)

例えば、ローカル用に sea.properties があっても、productionの方にも sea.properties があった場合、本番環境では production の sea.properties が利用されます。一方で、ローカル用に land.properties があって、他の環境で同じファイルが一切なければ、どの環境でもローカル用のものが利用されます。

allpackageは、結合環境や本番環境など、パッケージングされてデプロイされる環境における共通の領域です。 例えば、logback.xml などは結合環境でも本番環境でも設定が変わらないのであれば、allpackageに置くとよいでしょう。

Mavenの profile 設定は、common, webプロジェクトそれぞれの pom.xml にあります。baseに入れていないのは、webとcommonで設定が変わる可能性があるだろうということで、あえて共通化していません。 もし、webプロジェクトを増やすときに、webの共通pomを作った場合は、webのprofile設定はそちらで一元管理するとよいでしょう。

Maven の Profile 方式を使うときは、lastafluteMap.dfprop にて、environmentList を設定して、isUseLastaEnv を false にすると、Profile方式に追従して PropertiesHtml などが生成されるようになります。

環境切り替え用のproperties

_env.propertiesの置き場所は、maven の profile の通りに。

e.g. リファレンス実装のMaihamaプロジェクトでの環境ごとのProperties @Directory
maihama-common
 |-src/main/resources
 |  |-maihama_config.properties // 環境依存しないコンフィグ
 |  |-maihama_env.properties // ローカル環境用のコンフィグ (環境ごとにコピーされる)
 |
 |-src/main/integration
 |  |-maihama_env.properties // 結合環境用のコンフィグ
 |
 |-src/main/production
 |  |-maihama_env.properties // 本番環境用のコンフィグ

環境ごとのReplaceSchema

もし、結合環境のDBを ReplaceSchema で管理するときのために、DB接続先などを切り替えることができます。 ちなみに、本番では ReplaceSchema は絶対にやりませんので、結合とか検証環境においてのみの話です。

DBFluteの環境ごとのdfpropの切り替えを使って実現します。

例えば、integration だったら...

e.g. 結合DB(integration)のためのReplaceSchemaのdfprop構成 @Directory
DBFluteクライアント // dbflute_maihamadb とか
 |-dfprop
 |  |-integration
 |  |  |-databaseInfoMap+.dfprop // 結合DBへの接続先を設定
 |  |  |-replaceSchemaMap+.dfprop // 結合でのReplaceSchemaの微調整
 |  |
 |  |-...dfprop
 |  |-databaseInfoMap.dfprop
 |  |-replaceSchemaMap.dfprop
 |  |-...dfprop
 |
 |-log
 |-output
 |-...
 |-__integration_manage.sh // 結合への環境タイプが設定されたmanage

databaseInfoMap+.dfpropには、結合DB用の接続情報を差分で設定します。

e.g. 結合用の databaseInfoMap+.dfprop の設定 @databaseInfoMap.dfprop
map:{
    ; url      = jdbc:mysql://integration.maihamadb.org:3306/maihamadb
    ; schema   =
    ; user     = integrationdb
    ; password = integrationdb
}

replaceSchemaMap+.dfpropには、結合DBに登録するテストデータの選択、システムユーザーによるスキーマの自動作成をするかどうかなどの微調整を設定します。

例えば、特に結合DB専用のテストデータを用意していないのであれば、repsEnvType は ut で。もし、用意する場合は、repsEnvType を integaration に修正。 (テストデータをローカル用と結合用と分けて管理するのは、なかなかリソース的に難しい可能性があるので、とりあえずはutでもOKかと)

また、システムユーザーによるスキーマの自動作成をしないのであれば、additionalUserMapは空っぽで上書き。 使いたい場合は本体のdfpropを真似て設定しましょう。 (結合に関しては、そこまで自動化しなくても手間はあまりかからないので、ここでは空っぽで紹介しています)

e.g. 結合用の replaceSchemaMap+.dfprop の設定 @replaceSchemaMap.dfprop
map:{
    # same as UT for now
    ; repsEnvType = ut

    # no system user here
    ; additionalUserMap = map:{
    }
}

__integration_manage.sh は、manage.sh をコピーして、DBFLUTE_ENVIRONMENT_TYPE が設定されただけのものです。 それにより、結合用のDB接続先が有効になって、結合DBに対してアクセスできます。

e.g. 結合用の manage の中身 @__integration_manage.sh
...

export DBFLUTE_ENVIRONMENT_TYPE=integration

sh $DBFLUTE_HOME/etc/cmd/_df-manage.sh ...
taskReturnCode=$?

...

新しいデプロイ環境をつくるなら

新しい環境 (profile) をつくる場合は、いくつかの設定ファイルを修正していく必要があります。

例えば、pom.xml の修正や resources フォルダの追加、lastafluteMap.dfprop の environmentList など、幾つかの手続きを踏む必要があります。

お手軽 Logic 環境切り替え

TODO jflute EnvDispatchアノテーションのこと書く (気になる人はとりあえずJavaDocを)