flywayで環境(開発・テスト・本番)ごとにデータベースの接続先を切り替える
このブログは個人の調査および見解によって書いたものです。実際に以下の内容を使われる場合は自己責任でお願いします。
flywayとは
flywayはJavaでデータベースのマイグレーションを行うためのツールです。
JavaでWEBアプリケーションを作っていて、Ruby On Railsのようにスキーマのマイグレーションを実行したいと思って、Googleで探したところヒットしたので使ってみました。
前提条件
ソフトウェア | バージョン |
---|---|
Gradle | 1.9 |
flyway | 3.0 |
MySQL | 5.1.73 |
実行方法(基本編)
ちなみに、flywayをGradleで使う方法はドキュメント(http://flywaydb.org/documentation/gradle/)に書いてあります。
build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.flywaydb:flyway-gradle-plugin:3.0'
}
}
flyway { url = 'jdbc:mysql://localhost:3306/example' user = 'app_user' password = 's3cret' }
src/main/resources/db/migrateにSQLのスクリプトを配置します。 SQLファイルには命名規則があり、先頭大文字Vで始まり、バージョン、(アンダースコア)2つ、説明と続きます。 バージョンと説明は(アンダースコア)または.(ドット)で区切ることが可能です。
V0.0.1__create_todo.sql
create table todo( id INTEGER NOT NULL AUTO_INCREMENT ,title VARCHAR(30) ,description TEXT ,PRIMARY KEY (id) )
Gradleの実行
./gradlew flywayInit
上記タスクを実行すると、スキーマにschema_versionテーブルが作成されます。 このテーブルがマイグレーションをどこまで実行しているかを保持します。
./gradlew flywayMigrate
上記タスクでマイグレーションが実行されます。
環境ごとにデータベースの接続先を分ける場合
ちなみに、正しいアプローチなのかは不明です。こういうツールの場合は、すでにこのような機能が実装されていることを期待していたのですが、今の時点では機能が見つかっていないため、以下の実装にしました。
build.gradle
flyway { def enviroment = 'development' switch(enviroment) { case "development" : url = 'jdbc:mysql://localhost:3306/example_development' user = 'app_user_development' password = 'development_s3cret' case "test" : url = 'jdbc:mysql://test-database:3306/example_test' user = 'app_user_test' password = 'test_s3cret' case "production" : url = 'jdbc:mysql://database:3306/example_production' user = 'app_user' password = 'producition_s3cret' default : //Same development url = 'jdbc:mysql://localhost:3306/example_development' user = 'app_user_development' password = 's3cret' } }
以下の方法で実行します。
./gradlew flywayMigrate -Pflyway.enviroment=production
flywayは Gradleタスクに-Pを付与することで、実行時にプロパティを指定できます。
以上です。
SpringのDIコンテナについて
いまどきのJavaを使ったWEBアプリケーション開発を使いたいと思い調べたSpringの基本のメモです。
DIコンテナ
SpringのDIコンテナを使うとオブジェクトの依存関係を簡単に解決できるとのこと。アスペクト指向プログラミングの詳しいことは分からないので、これから勉強していきたいと思います。
コードの具体例
ちなみに、Springのバージョンは4.0.4です。
src/main/hello/person.java
public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } }
ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"services.xml"}); Person john1 = (Person)ctx.getBean("person");
src/main/resources/services.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="person" class="hello.Person"> <constructor-arg index="0" value="john" /> <constructor-arg index="1" value="11" /> </bean> </beans>
Personクラスのコンストラクタに"john"と"11"を設定してインスタンスを生成しています。 DIコンテナを使わないとnewでコンストラクタに引数を指定して生成しますが、DIコンテナの場合は その記載が不要です。
こんな書き方も出来ます。
Person john2 = ctx.getBean("person", Person.class);
DIコンテナのスコープ
ちなみに、SpringのDIコンテナにはスコープがあり、デフォルトはシングルトンです。なので、scopeを指定せずに複数のオブジェクトを生成してもインスタンスは1つです。都度新しいインスタンスを生成する場合は、beanに以下のように設定します。
<bean id="person" class="hello.Person" scope="prototype">
DIコンテナのメリット
何が便利かというとユニットテストが書きやすい。あと、クラスがプラッガブルになるのでクラスの差し替えが容易です。 今後はWEBアプリケーションの構築に向けて理解を深めていきたいと思います。
ScalaのUnitについて
Scalaでよく見かけるUnitがわからなかったので、調べてみました。
以下の様なコードで戻り値を示す際に使われています。
def hoge(): Unit = { println("hoge") } hoge()
http://www.scala-lang.org/api/current/index.html#scala.Unit
Scalaのリファレンスを見ると、Javaのvoidのようなものと書いてあります。
Scalaの設計思想として関数型プログラミングの考え方があります。ここでいう
関数とはC言語のような言語で処理を定義するという意味の関数ではなく、数学
で使う必ず値を戻す関数のことです。
Scalaは戻り値を返さなければならないけれども、voidのように使える値がない
と不便なので定義されていると理解しました。
RSpec + Seleniumを試す。
個人的な備忘録です。この記事は個人の理解によって書いたものであり、内容を保証するものではありません。
1.Seleniumとは
Java, Ruby, Pythonなどの言語からWEBブラウザを操作するためのAPIです。Seleniumを使うと実際にブラウザが起動して処理が実行されます。
詳細は本家のページ(http://seleniumhq.org/)に書いてあります。
2.今回のテーマ
インテグレーションテストを自動化するために、RSpecからSeleniumを使いたいと思います。なぜ、RSpec + Seleniumなのかというところですが、RSpecはRubyのテスト用ライブラリでRubyならではの生産性の高さが魅力です。Rubyを使うという意味ではTest::Unitも選択肢にありますが、個人的にRSpecを使ったほうが読みやすいコードを書きやすいと思います。
Seleniumを使う理由ですが、テストをWEBアプリケーションを作っている言語で書かなくてもよいということがあります。例えば、Javaでアプリケーションを作ったので、インテグレーションテストもJavaで書くというのは個人的に避けたいです。Javaはコンパイルによる静的チェックや継承の制限、JVMの解析によるパフォーマンス分析のやりやすさが魅力で、チームでの開発では魅力的な言語ですが、Rubyと比較すると記述が冗長な部分があり、言語レベルでの生産性の高さではRubyの方が優れていると思います。WEBアプリケーションはJavaで作ったけど、テストを効率的に書きたいというときに選択肢の一つとして、Ruby+Seleniumはありだと思っています。
ちなみに、状況によりますが、Railsなどのテストがサポートされているフレームワークでは、インテグレーションテストもそのフレームワークのルールに従って作るほうが効率がいい場合もあると思います。
3.試してみる
開発環境はMac OS X 10.8.2 でrvmを使っています。APIのリファレンスはhttp://selenium.googlecode.com/svn/trunk/docs/api/rb/index.htmlを参考にしました。テストを実行するプログラムのディレクトリ構成は以下のとおりです。
selenium_rspec |- spec |- vendor |- .rspec |- .gitignore `- Gemfile
ライブラリの管理はbundleを使います。Gemfileは以下のとおりです。
source "http://rubygems.org" gem 'rspec' gem 'selenium' gem 'selenium-webdriver'
bundleでgemをインストールします。
bundle install --path vendor/bundle
specディレクトリに以下のプログラムを配置します。ちなみに、使うブラウザによってWebDriverを生成するコードが異なります。今回は最もシンプルなFireFoxで試しました。RSpecではspec/**/*_spec.rbにマッチするファイルを自動で認識して実行してくれますので、その規約にそってファイルを作ります。
firefox_example_spec.rb
require 'selenium-webdriver' describe "Google", "FireFox Example" do before do @webdriver = Selenium::WebDriver.for :firefox end it "Http get should be successfull." do @webdriver.navigate.to "http://www.google.co.jp" element = @webdriver.find_element(:name, 'q') element.send_keys "Hello World" element.submit @webdriver.title.should == "Google" end after do @webdriver.quit end end
Googleにアクセスして、HelloWorldと入力するテストです。Matcherではページのタイトルが"Google"であることを検証しています。
プロジェクトのルートで以下のコマンドを実行すると、ブラウザが起動してテストが自動実行されます。
bundle exec rspec
ちなみに、プロジェクトルートに.rspecファイルを配置すると、カラー表示や結果の表示を変更できます。
.rspec
--format documentation --color
今後はJenkinsとの連動にチャレンジしたいと思います。
Rails 勉強会 東京 第68回まとめ
11/19(土)にRails勉強会@東京 第68回に参加してきました。そのまとめです。
1.概要
参加者は20人位でした。初参加の方が多かったという印象です。今回はファシリテーションを任せて
いただけたので、私がセッションを仕切らせてもらいました。
(1) 全体の流れ
セッション1:カッコイイUIを簡単につくる。/ 初心者向けセッション
セッション2:テストの話
セッション3:Rails3.1の機能
2.セッション1 :カッコイイUIを簡単につくる。
出来る限りCSSを書かずに、カッコイイUIを作りたいというテーマで話がありました。
(1) twitter bootstrap の紹介
http://twitter.github.com/bootstrap/
git からソースを取得してコードも簡単に読みました。
https://github.com/dannymcc/Support-Systemからbootstrapを使ったオープンソースプロダクト
をgit cloneして、実際に動かして紹介しました。
(2) ExtJS(javascriptライブラリ)の紹介
http://extjs.co.jp/
デモを簡単に見ました。
(3) backbone.jsの紹介
http://documentcloud.github.com/backbone/
概要だけ紹介しました。次回はこれを使ったアプリの紹介とかが出来るといいかもしれないという
話になりました。
(4) まとめ
UIを簡単につくるための方法として、様々な選択肢があって、それはお客さんの望む内容や、アプリ
ケーションの仕様によって決めるべきという話でした。
初心者向けセッションには参加しなかったので、ここでは書きません。
3.セッション2:テストの話
(1) テスト駆動開発の話
テストコードを作ることにこだわり過ぎないことも大切。
まずは動くものを作って、APIを良く考えなければいけないときにテストコードから作るという考え方もある。
(2) rspecで書かれたテストコードのソースコードリーディング
https://github.com/resolve/refinerycms/blob/master/dashboard/spec/requests/refinery/admin/dashboard_spec.rb
TDDのライブコーディングにトライしようという流れでしたが、ライブコーディングは準備していないと
失敗する可能性が高いので、ソースコードリーディングをしました。
4.セッション3:Rails 3.1の機能
(1) Asset Pipelineの紹介
(a) SCSSの紹介
(b) Coffee Scriptの紹介
(2) Http Streamingの紹介
(3) マウント可能なエンジンの紹介
http://ja.asciicasts.com/episodes/277-mountable-engines
(4) Rails 3.0からRails 3.1へのバージョンアップ
標準の機能でアップグレードできるところはする。routes.rbとか標準のツールで出来ないところ
は、gemで便利なツールをインストールして使う。
あと、時間が余ってしまったので、参加者の方に開発環境を聞きました。
ちなみに、emacsを使ってる人はおらず、vimが大多数でした。IDEも聞いてみたところ、
NetBeansを使っている人が数名いらっしゃって、Aptanaを使っている人はいませんでした。
Aptanaは重いようです。
5.最後に
勉強会を開催してくださった永和システムマネジメントの方、参加者のみなさんありがとうございました。
CentOSにZabbix 1.8.8をソースコードからビルドする。
CentOSにZabbixをインストールします。この記事ではhttpdとphpもソースコードからビルドします。
1.ソフトウェアのバージョン
CentOS 5.5 x86_64
Zabbix : 1.8.8
MySQL : 5.5.8
Apache : 2.2.17
php : 5.3.4
libpng : 1.5.5
libjpeg : 8c
net-snmp:5.7.1
2.作業の前提条件
(1) rootユーザで作業します。
(2) ソースはダウンロードして、/usr/local/srcに配置されているものとします。
(3) MySQLはすでにインストールしてあるものとします。
MySQLのインストール手順はhttp://d.hatena.ne.jp/pgmgonta/20110308/1299593213を参照してください。
3.httpdのインストール
(1)apacheユーザの追加
groupadd apache useradd -g apache apache
(2) ディレクトリの作成
mkdir /usr/local/httpd
(3) httpdのビルド
cd /usr/local/src tar -zxvf httpd-2.2.17.tar.gz cd httpd-2.2.17 ./configure --enable-so --prefix=/usr/local/httpd/ make && make install
(4) ディレクトリのアクセス権変更
chown -R apache:apache /usr/local/httpd/
(5) 起動
以下のコマンドを実行してから、「http://サーバのIPアドレス」へ接続してください。HTTPレスポンスが帰ってくれば成功です。
/usr/local/httpd/bin/apachectl start
4.phpのインストール
(1) 依存するライブラリをmakeします。
libjpegをmakeします。
cd /usr/local/src tar -zxvf jpegsrc.v8c.tar.gz cd jpeg-8c/ ./configure make && make install
libpngをmakeします。
cd /usr/local/src tar -zxvf libpng-1.5.5.tar.gz cd libpng-1.5.5 ./configure make && make install
(2) phpのビルド
phpをビルドします。Zabbixを動かすために必要なconfigureオプションを指定します。
cd /usr/local/src tar -zxvf php-5.3.4.tar.gz cd php-5.3.4 ./configure --with-mysql=/usr/local/mysql/ --enable-zip --enable-mbstring --enable-bcmath --with-gd --with-apxs2=/usr/local/httpd/bin/apxs --enable-sockets make && make install
5.Zabbixのインストール
(1)zabbixユーザの追加
groupadd zabbix useradd -g zabbix zabbix
(2) net-snmpのビルド
cd /usr/local/src tar -zxvf net-snmp-5.7.1.tar.gz cd net-snmp-5.7.1 ./configure ここではコンソールに値を入力しながらインストールします。デフォルト値で特に問題はありません。 make && make install
(3) Zabbixのビルド
tar -zxvf zabbix-1.8.8.tar.gz cd zabbix-1.8.8 ./configure --enable-server --with-mysql=/usr/local/mysql/bin/mysql_config --with-net-snmp --with-libcurl make && make install
(4) Zabbixの設定ファイルの配置
mkdir /etc/zabbix cp misc/conf/zabbix_server.conf /etc/zabbix/
(5) Zabbixの自動起動の設定
cd /usr/local/src/zabbix-1.8.8 cp misc/init.d/redhat/8.0/zabbix_server /etc/init.d/ chmod +x /etc/init.d/zabbix_server chkconfig --add zabbix_server chkconfig zabbix_server on
/etc/init.d/zabbix_serverの内容を書き換えます。
#progdir="/usr/local/zabbix/bin/" progdir="/usr/local/sbin/"
(6) php.iniの変更
php.iniは/usr/local/libに配置します。
cd /usr/local/src/php-5.3.4 cp php.ini-development /usr/local/lib/php.ini
php.iniを編集します。
diff php.ini-development /usr/local/lib/php.ini 440c440 < max_execution_time = 30 --- > max_execution_time = 600 450c450 < max_input_time = 60 --- > max_input_time = 600 458c458 < memory_limit = 128M --- > memory_limit = 256M 728c728 < post_max_size = 8M --- > post_max_size = 32M 879c879 < upload_max_filesize = 2M --- > upload_max_filesize = 16M 993c993 < ;date.timezone = --- > date.timezone = Asia/Tokyo
6.Zabbixの起動
Zabbixを起動させるために、net-snmpとmysql-clientのライブラリを参照できるようにします。
vi /etc/ld.so.conf.d/net-snmp.conf
/etc/ld.so.conf.d/net-snmp.confの内容
/usr/local/lib
vi /etc/ld.so.conf.d/net-snmp.conf
/etc/ld.so.conf.d/mysql.confの内容
/usr/local/mysql/lib
Zabbixを起動します。
service zabbix_server start
7.WEBインタフェースの設定
(1)プログラムの配置
phpのプログラムを配置します。
mkdir /usr/local/httpd/htdocs/zabbix cd /usr/local/src/zabbix-1.8.8 cp -Rp frontends/php/* /usr/local/httpd/htdocs/zabbix/
(2)MySQLの設定
MySQLにテーブルを作成して、データを登録します。
/usr/local/mysql/bin/mysql -u root > create database zabbix; > grant all on zabbix.* to zabbix@localhost identified by "PASSWD"; > flush privileges; > exit cd /usr/local/src/zabbix-1.8.8 /usr/local/mysql/bin/mysql -u zabbix -D zabbix -p < create/schema/mysql.sql /usr/local/mysql/bin/mysql -u zabbix -D zabbix -p < create/data/data.sql /usr/local/mysql/bin/mysql -u zabbix -D zabbix -p < create/data/images_mysql.sql
(3)Apacheの起動
/usr/local/httpd/bin/apachectl start
以下のページへアクセスしてセットアップしてください。
http://ZABBIXサーバのIPアドレス/zabbix/index.php
作業は以上です。
CentOSにSyslog-ng 3.1.1をソースコードからビルドする。
1.環境
OS : CentOS 5.5(64bit)
Syslog-ng : Syslog-ng 3.3.1 オープンソースエディション
2.インストール作業
ここでは作業を開始する前に、/usr/local/srcに以下(1)と(2)のファイルが配置されているものとします。
(1) eventlog_0.2.12.tar.gz
(2) syslog-ng_3.3.1.tar.gz
eventlogからインストールします。作業はrootユーザで行います。
インストールするために、環境変数を設定します。
vi ~/.bash_profile
以下の内容を追記します。
〜省略〜 PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH export PKG_CONFIG_PATH 〜省略〜
~/.bash_profileを反映します。
. ~/.bash_profile
eventlogをビルドします。
cd /usr/local/src tar -zxvf eventlog_0.2.12.tar.gz cd eventlog-0.2.12/ ./configure make && make install
syslog-ngをビルドします。
cd /usr/local/src tar -zxvf syslog-ng_3.3.1.tar.gz cd syslog-ng-3.3.1/ ./configure make && make install
cd /usr/local/src/syslog-ng-3.3.1 cp contrib/init.d.RedHat-7.3 /etc/init.d/syslog-ng chmod +x /etc/init.d/syslog-ng chkconfig --add syslog-ng
以下のコマンドで設定を確認します。稼動させたいランレベルでonになっていることを確認します。
chkconfig --list syslog-ng
標準のsyslogを停止します。合わせて、syslogの自動起動をOFFにします。
service syslog stop chkconfig syslog off
/usr/local/varディレクトリが存在しない場合は、以下のコマンドで作成してください。
mkdir /usr/local/var
設定ファイルはデフォルトで以下のパスに配置されます。必要に応じて変更してください。
/usr/local/etc/syslog-ng.conf
syslog-ngを起動します。
service syslog-ng start
3.動作確認
loggerコマンドで確認します。
tail -f /var/log/messages
logger "test"
作業は以上です。