2013年10月31日木曜日

mavenとtestngでJavaのテストコードをモダンに開発

■概要
rubyやpython, phpなどのスクリプト言語にあるパッケージ管理ツール「gem」「easy-install」「composer」などを使って
サーバサイド上で簡単にソースが書けちゃうってやつを頑張ってJavaでやるとこうなったというのを紹介します
頑張れば、できなくなないです。。。

■環境
CentOS 5.9 64bit
maven 3.1.0
Java 1.7.0_05
※Javaのインストールに関しては
http://kakakikikeke.blogspot.jp/2012/06/centosjenkinsjavatomcatantgit.html
※mavenのインストールに関しては
http://kakakikikeke.blogspot.jp/2013/10/maven.html

■開発
1. mvnプロジェクトを作成する
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=com.kakakikikeke.test -DartifactId=Sample_Test

2. testngをダウンロードする
vim pom.xml
<dependencies>...</dependencies>の間に以下を追記する
※記載したあ、とデフォルトで入っているJUnitのdependencyの記載を削除して大丈夫です
<dependency>
  <groupId>org.testng</groupId>
  <artifactId>testng</artifactId>
  <version>6.3.1</version>
  <scope>test</scope>
</dependency>
mvn clean
mvn compile

すると以下のローカルのリポジトリにパスにjarファイルがダウンロードされます
/root/.m2/repository/org/testng/testng/6.3.1/
※mvn clean と mvn compile はやらなくても記載して保存した段階で勝手にmavenがダウンロードしてきてくれます

3. テストケースを書く(サンプル)
vim src/test/java/com/kakakikikeke/test/AppTest.java
package com.kakakikikeke.test;

import org.testng.annotations.Test;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.AfterTest;

public class AppTest {

  @BeforeTest
  public void beforeTest() {
    System.out.println("beforeTest");
  }

  @AfterTest
  public void afterTest() {
    System.out.println("beforeTest");
  }

  @Test
  public void TestCase1() {

  }
}
と記載したら

mvn clean
mvn test-compile
mvn test

でtestngのテストが実行されます
あとはTestCase1に肉付けして行ったり、TestCase2を作成したりすれば一応「mvn」コマンドだけでテストケースを書いて実行することができます


とここまで環境が整っていざ開発となると、実は正直かなりめんどくさかったです。。。
以下、具体的にいけてない感じた点です
  • ライブラリを追加するときにいちいち maven repository から必要なライブラリを見つけてそのXML情報をpom.xmlに記載する必要がある
  • maven repository の検索性能がイマイチで自分が必要としているライブラリがなかなか見つからない
  • 全然関係ないライブラリを追加していることがある
  • mvn clean から test までの流れを毎回やるのが正直めんどくさい(シェルを一つ書いて一回でできるようにするとか独自のgoalを作るとかはありますが)
  • やっぱりJavaはサジェストがエディタににないと厳しい(このへんは emacs とかでもなんとかなりますが、準備が大変。。。)
といった印象を受けました
最終的にはあきらめて「mvn eclipse:eclipse」とかでeclipse形式に吐き出してeclipseにインポートして開発するのが一番楽なのかなと思ってしまった次第です
本当に枠組みだけ作るのであれば紹介した手順だけでもいいのかなーと思いました

2013年10月30日水曜日

【Windows7】デスクトップに通知できるgrowlをインストール

■概要
growl(ぐろーる)はMac用に作られたデスクトップ通知アプリです
今回はWindows7版のgrowlをインストールして通知テストを実施したいと思います

■growlのインストール
http://www.growlforwindows.com/gfw/
のサイトからWindows版のgrowlをダウンロードします
2013/10/25段階での最新版は2.0.9でダウンロードリンクは以下にありました


インストール時は特に何も気にすることなくNextと押していけば大丈夫です
デフォルトの設定だと「C:\Program Files (x86)\Growl for Windows」にインストールされるようです

■基本設定
まず、growlを起動します
起動するとタスクトレイにgrowlのアイコンが出現するのでダブルクリックで設定ダイアログを表示します
・General → Automatically start Growl at login にチェックをする
とりあえず上記のみ設定しました

次に、コマンドプロンプトを立ちあげて以下のように実行します
cd C:\Program Files (x86)\Growl for Windows
growlnotify.exe aaa
growlは基本的にコマンドから実行して使います
上記を実行するとデスクトップ上に通知が表示されると思います

そして、growlのApplicationタブを選択すると先ほど実行したコマンドがアプリケーションとして追加されます
通知のデザイン等を変更できるのでお好みに合わせて変更してください(任意)

とりあえずインストールとテスト通知は以上です
アプリを自分で追加することで独自の通知をすることは可能ですが、すでにたくさんのアプリがあるので以下から取得することも可能です
http://www.growlforwindows.com/gfw/apps.aspx

時間があったら独自の通知アプリでも作ってみたいと思います

2013年10月29日火曜日

【Zabbix】net.tcp.serviceを使う際の注意事項

■環境
CentOS 6.3 64bit
Zabbix 2.0.3

■注意事項
net.tcp.serviceはポートの状態を確認することができるキーです
LISTEN可能な状態なら1が返ってきます

net.tcp.serviceは引数を3つ設定でき
  • 1つ目はプロトコル(ssh、service.ntp、ldap、smtp、ftp、http、pop、nntp、imap、tcpのいずれか1つを指定)
  • 2つ目はIPアドレス
  • 3つ目はポート番号
を指定するのですが、LISTENしているIPアドレスによって2つ目の引数の設定に注意してください

以下具体例です
  • ポート10052が127.0.0.1でLISTEN -> net.tcp.service[tcp,,10052]
  • ポート10052が0.0.0.0でLISTEN -> net.tcp.service[tcp,,10052]
  • ポート10052が192.168.1.10でLISTEN -> net.tcp.service[tcp,192.168.1.10,10052]

何も指定しないとデフォルト監視しに行くのIPアドレスは「127.0.0.1」となります
0.0.0.0でLISTENしている場合は127.0.0.1でもアクセスできるので何も指定しなくても大丈夫です
厄介なのが192.168.1.10(とかプライベートIP系)でLISTENしている場合で
IPアドレスを指定しないと127.0.0.1に聞きに行ってしまうのでうまく監視できません
なのでちゃんとIPを指定してあげないとずっと「0」が返ってきてしまいます

ブログ等の紹介はIPアドレスまでちゃんと指定しているケースが少ないので
ちゃんと引数が何を意味しているのかはちゃんと調べないとダメですね

■参考サイト

2013年10月28日月曜日

【ruby】invalid multibyte char (US-ASCII)

先頭に以下を追加する

# encoding: utf-8

いつも忘れのでメモ

2013年10月27日日曜日

mavenコマンドの使い方(主にgoal)について調べたのでメモ

■環境
CentOS 5.9 64bit
maven 3.1.0
Java 1.7.0_05
mavenのインストール方法は以下を参照
http://kakakikikeke.blogspot.jp/2013/10/maven.html

■プロジェクトの作成
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=com.mycompany.app -DartifactId=my-app

通常のJavaプロジェクトを作成する場合のパラメータです
archetypeGroupIdは後述にもありますが、mavenで用意されたテンプレートみたいなものを設定します(独自で作成することも可能)
groupIdはいわゆるパッケージ名です
artifactIdはいわゆるプロジェクト名です

コマンド実行時に入力が必須の部分もあるので入力必須の項目のサンプルを以下に記載します
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 312:
  enter入力
Choose org.apache.maven.archetypes:maven-archetype-quickstart version:
  enter入力(1.1)
Define value for property 'version':  1.0-SNAPSHOT: :
  enter入力
確認
  Confirm properties configuration:
  groupId: com.mycompany.app
  artifactId: my-app
  version: 1.0-SNAPSHOT
  package: com.mycompany.app

■goal検証
maven自体にはgoalと呼ばるmvnコマンドに渡す引数がいろいろと用意されており
そのgoalの指定によりjarを作ってくれたりとかテストしてくれたりとか.classファイルを作ってくれたりとか振る舞いが変わってきます
基本はこのgoalの種類と動きがある程度わかっていればmvn自体は使えるようになると思います

またプラグインという概念があり、振る舞いをいろいろと変更、拡張できるのでメジャーなプラグインさえ覚えておけば大丈夫だと思います
プラグインは独自で作成することも可能です

ここで紹介するgoalやプラグインが全てではないので他のgoalについては以下のページなどを確認してください
http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html

以下で紹介するコマンドはプロジェクト配下のディレクトリ(今回だとmy-app)配下でpom.xmlがあるところで実行してください

・mvn compile
target/classes 配下にjavaコンパイルした.classファイルを作成してくれます

・mvn test-compile
target/test-classes 配下にコンパイルしたテスト用.classファイルを作成してくれます

・mvn test
target/classes 配下にjavaコンパイルした.classファイルを作成し
target/test-classes 配下にコンパイルしたテスト用.classファイルを作成し
target/surefire-reports 配下にテスト結果を作成してくれます
mavneデフォルトのテストツールは「JUnit」となっておりpom.xml内でdependencyが定義されています

・mvn package
target 配下にjarファイルを作成し
target/classes 配下にjavaコンパイルした.classファイルを作成し
target/test-classes 配下にコンパイルしたテスト用.classファイルを作成し
target/mavne-archiver 配下にpom.properties(プロジェクトのメタ情報ファイル?要調査)を作成し
target/surefire-reports 配下にテスト結果を作成してくれます
「jar:jar」「compile」「test-compile」「test」等をまとめて実行してくれるgoalです
test結果に関してはSurefireプラグインというプラグインを使っているようでテスト結果を統計的に見れるファイルも作成してくるようです
http://maven.apache.org/surefire/maven-surefire-report-plugin/

・mvn clean
target ディレクトリを削除してくれます
「compile」「test-compile」「test」「package」等を実行する前には実行する必要があります

・mvn install
作成した成果物(jarファイル)をローカルのmavenリポジトリに配備してくれます
具体的なパスは例えばrootユーザで実行した場合は
/root/.m2/repository/com/mycompany/app/my-app/1.0-SNAPSHOT/
配下にjarやxmlファイルを展開してくれます
他のプロジェクトが成果物を参照する必要がある場合に実施します

・mvn archetype:generate
指定できる主なオプションは以下があります
  • -DarchetypeGroupId・・・作成するプロジェクトの元となるarchetypeを入力します
  • -DgroupId・・・パッケージ名を入力します
  • -DartifactId・・・プロジェクト名を入力します
groupIdやartifactIdは任意の値を入力することができます
archetypeGroupIdに関してはMavenCentralで公開されているarchetypeGroupIdを指定しなければいけません
ただ量が膨大で覚えるのはほぼ不可能です
なので省略することもでき、省略した場合はプロジェクトを作成するときにどのarchetypeGroupIdを使用するか選択することができます
一覧がずっと出てきて番号を入力することでarchetypeGroupIdを選択することができます
ただ、この一覧もものすごい量が出てくるので選択するのが結構大変です

・mvn site
pom.xmlをもとにプロジェクトの情報をHTML形式に吐き出してくれます
現在使用しているプラグイン読み込んでいるjarファイルの一覧等が確認できます

・mvn idea:idea
InteliJ形式のフォルダ構成に変換してくれる
InteliJからインポートすればコマンドで作成したプロジェクトをInteliJ上で開発できます
my-app.iml, my-app.ipr, my-app.iwsを作成してくれます

・mvn eclipse:eclipse
上記のeclipse版
.classpath, .projectを作成してくれます

■プラグインに関して
主なプラグインについて紹介します
デフォルトの状態でもメジャーなプラグインはすぐに使える状態にあります

・mvn jar:jar
target 配下にjarファイルを作成してくれます
http://maven.apache.org/plugins/maven-jar-plugin/

・mvn war:war
target 配下にwarファイルを作成してくれます
http://maven.apache.org/plugins/maven-war-plugin/

今回の場合通常のJavaプロジェクトでWebアプリ用のプロジェクトではないので失敗すると思います
具体的にはweb.xmlの定義に失敗するのですが、冒頭のプロジェクト作成時の
archetypeGroupIdをwebアプリ用で指定してプロジェクトを作成するとwarファイルの作成もうまくいきます
サンプルは以下の通りです
mvn archetype:generate -DarchetypeGroupId=maven-archetype-webapp -DgroupId=com.mycompany.web.app -DartifactId=my-web-app

他のarchetypeGroupId関しては以下を参照してみてください
http://maven.apache.org/guides/introduction/introduction-to-archetypes.html

■所感
mavenリポジトリがグローバルにアクセスできないと使えないのでグローバルに接続できる環境は必須
プロキシ等の環境の場合、pom.xmlを修正しないといけない等、若干ハードルが高くなる

■参考

2013年10月26日土曜日

elasticsearchを試してみた

■環境
CentOS 5.9
Java 1.7.0_05
elasticsearch 0.90.5

■elasticsearchインストール
wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-0.90.5.tar.gzs
tar xvzf elasticsearch-0.90.5.tar.gz
mv elasticsearch-0.90.5 /usr/local/
cd /usr/local/
ln -s elasticsearch-0.90.5/ elasticsearch

vim /root/.bashrc
export ELASTIC_SEARCH=/usr/local/elasticsearch
export PATH=$ELASTIC_SEARCH/bin:$PATH
source /root/.bashrc

elasticsearch -f
netstat -an | grep 9200
最終的に9200ポートでLISTENしていればインストールおよび起動は完了

■サンプル実行
1. サンプルデータの投入
curl -X POST http://localhost:9200/dictionary/name/1 -d '{"famiry_name":"kaka","first_name":"abc","email" :"sample@sample.email.com","age":20}'
curl -X POST http://localhost:9200/dictionary/name/2 -d '{"famiry_name":"kaka","first_name":"def","email" :"sample@sample.email.com","age":20}'
curl -X POST http://localhost:9200/dictionary/name/3 -d '{"famiry_name":"kaka","first_name":"ghi","email" :"sample@sample.email.com","age":20}'
curl -X POST http://localhost:9200/dictionary/name/4 -d '{"famiry_name":"kaka","first_name":"jkl","email" :"sample@sample.email.com","age":20}'
curl -X POST http://localhost:9200/dictionary/name/5 -d '{"famiry_name":"kaka","first_name":"mno","email" :"sample@sample.email.com","age":20}'
「/hoge/foo/n」のような感じでパスを自由に設定することができます
n の部分は数字を設定する必要があります
最後の数字の n 部分を変えてデータをPUTしないと同じデータをタダ上書きするだけなので注意が必要です

2. サンプルデータの取得(キーワード検索)
curl -X GET http://localhost:9200/dictionary/name/_search -d '{"query":{"match":{"famiry_name":"kaka"}},"size":10,"from":0}'
「/hoge/foo/_search」というパスにリクエストすることで検索することができます
今回はcurlコマンドなので-dでリクエストのbody部分を設定します
1. で登録した全てのデータが返ってくるはずです
sizeとfromはmysqlで言うところのlimitで範囲を指定して取得する場合などに使えます(デフォルトはsize:10, from:0のようです)
クエリの指定方法はたくさんありますので他のクエリの指定方法は以下を参考にしてみてください
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-uri-request.html

3. サンプルデータの取得(部分一致検索、正規表現検索)
curl -X GET http://localhost:9200/dictionary/name/_search -d '{"query":{"regexp":{"famiry_name":"ka.*"}},"size":10,"from":0}'
基本的な指定は2. と同様ですが「match」ではなく「regexp」を使用しております
使用できる正規表現は以下に詳しく記載があります
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-regexp-query.html

今回は以上です
elasticsearchはすべてをREST-API経由で実行するツールとなっています
データの検索に特化しており、全文検索や位置検索もできるようになっています
また応用編ですがhadoopにも対応しているので簡単にスケールアウトできるようです(未調査)

次回はelasticsearch用のWeb UI「kibana」でも試してみたいと思います

■Tips
・登録したすべてのルートパス(indexes)を表示する方法
curl -X GET http://localhost:9200/_aliases
・不要なindexesを削除する方法(_riverというindexes配下のデータをすべて削除する)
curl -XDELETE 'http://localhost:9200/_river

■参考

2013年10月24日木曜日

shellでjsonをパースする方法(メモ)

■概要
https://github.com/dominictarr/JSON.sh
を使用した方法を紹介します

■環境
CentOS 5.9
bash 3.2.25
Linux kernel 2.6.18-238.el5 x86_64

■設定(インストール)
wget https://github.com/dominictarr/JSON.sh/archive/master.zip
unzip master.zip
mv JSON.sh-master/ /usr/local/
ln -s JSON.sh-master/ json_parse
cd /usr/sbin/
ln -s /usr/local/json_parse/JSON.sh json_parse

■動作確認
echo '{"key":"value","key2":"value2","key3":{"food":"potate"}}' | json_parse -b
["key"] "value"
["key2"]        "value2"
["key3","food"] "potate"

「-b」を指定すると入力したjson情報は出力しません