平田です。
JBoss EAP (Wildfly) の設定値変更をスクリプト化し、Mavenのプラグインを使ってこのスクリプトを流せます。
まずMavenプロジェクトを新規作成し、スクリプトを書きます。
$ mvn archetype:generate ... $ mkdir -p src/main/cli $ touch src/main/cli/add-system-property.cli
#add-system-property.cli if (outcome != success) of /system-property=foo:read-resource /system-property=foo:add(value="bar") end-if
Mavenプラグインを設定します。
... <build> <plugins> <plugin> <groupId>org.jboss.as.plugins</groupId> <artifactId>jboss-as-maven-plugin</artifactId> <version>7.5.Final</version> <configuration> <execute-commands> <scripts> <script>src/main/cli/add-system-property.cli</script> </scripts> </execute-commands> </configuration> </plugin> ...
実行します。
$ mvn -Djboss-as.hostname=192.168.1.123 -Djboss-as.port=9999 -Djboss-as.username=admin -Djboss-as.password=********
テスト
設定値変更を自動化したら、その確認作業も自動化したいところです。Mavenに依存関係を追加しましょう。
<dependencies> <dependency> <groupId>org.jboss.as</groupId> <artifactId>jboss-as-cli</artifactId> <version>${version.jboss}</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${version.junit}</version> <scope>test</scope> </dependency> </dependencies>
テストを書きます。
public class ConfigurationTest { @Rule public ConfTestSupport support = new ConfTestSupport(); @Test public void datasourceExists() throws Exception { ModelNode response = support.execute("/system-property=foo:read-resource"); assertEquals("success", response.get("outcome").asString()); } }
ボイラープレートコードをサポートクラスに逃がしています。APIの使い方は、公式サイトのWikiを見てください。
で?
設定値の変更手順がMavenプロジェクトになり、確認行為も自動化したとなれば、次は執事のおっさんが出てくることになるでしょう。
執事のおっさんがコードをチェックアウトして実行するということは、人間がsshしてちまちま設定変更していった結果、秘伝のタレみたいに再現不可能になることもなくなりますね。また、インフラの設定値変更のワークフローがアプリケーション開発と同じ(手元で開発してチェックインする)になるのも助かります。
このあたりはChefを使って自動化し、serverspecで確認するのが普通のようです。このエントリーの方法だとJBossの設定にしか適用できないのですが、お手軽(Rubyのエコシステム怖いって人には)です。
ちょっと試した程度ですが、以下の様な工夫が必要です。
- 設定値変更スクリプトは「べき等」に作る。
- 手作業で設定値変更しない。
- 各環境(開発、自動テスト、UAT、本番など)ごとに異なる設定値(DB接続先など)は外部化する。
- JBossであればシステムプロパティ展開を使って環境間の差異を設定に埋め込まないようにする。
- CLIは汎用プログラミング言語とは程遠い表現力(変数無し、ループ無し、共通化できない)なので、APIを使ったコードやJVMスクリプトの方が良いかも?
- 設定値によってはデプロイメントを停止する必要がある(データソースの設定値を変える場合、そのデータソースを使うアプリを止める)。