2015年7月23日木曜日

Spring の @RequestMapping で OPTIONS メソッドを処理する方法

概要

Spring で OPTIONS メソッドのリクエストを受け取る方法を紹介します
普通に@RequestMappingmethod=RequestMethod.OPTIONSを指定するだけだとダメでした

環境

  • Mac OS X 10.10.3
  • Eclipse Luna 4.4.1
  • Spring Framework 4.1.6
  • Spring Tool Suite 3.6.4
  • Java 1.8.0_31
  • Maven 3.2.1

サンプルプロジェクト作成

過去の記事を参考に作成してください
Spring Framework のバージョンが最新でない場合は pom.xml 「org.springframework-version」のバージョン記載部分を最新のバージョンに変更してください

コーディング

@RequestMappingにOPTIONSメソッドを追加する

これだけだとダメという話をしましたが、これがないと始まらないので定義します

@RequestMapping(value = "/", method = {RequestMethod.GET, RequestMethod.OPTIONS})

既存のメソッドと同じマッピングで受け取る場合は中括弧を使って定義してください
もちろん上記を追加しただけだと、まだリクエストを受け取ることができません

web.xml に定義を追加する

web.xml<servlet>タグに以下を追記します

<servlet>
  <servlet-name>appServlet</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
    <param-name>dispatchOptionsRequest</param-name>
    <param-value>true</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>

おそらくweb.xml内に<servlet>タグはすでにあると思います
<servlet-name><servlet-class>がある場合は新規で追加しなくてOKなので過不足分を既存の<servlet>タグ内に追記すればOKです

web.xmlはSTSで作成していれば、src/main/webapp/WEB-INF/web.xmlにあります

動作確認

書き換えが完了したらアプリを再起動してOPTIONSメソッドのリクエストが処理されるか確認してみましょう
自分はいつもcurlコマンドで確認しますが、curl の場合は以下のようにするとOPTIONSメソッドのリクエストが送信できます

curl -v -X OPTIONS http://localhost:8080/test/

これで@RequestMappingアノテーションが付与されたメソッドが実行されればOKです

Tips

MockMVCを使っている場合に有効にする方法

上記の手順を実行すれば実際のアプリ側でOPTIONSメソッドのリクエストを取得することができます
ただ、テストの場合は有効になっていないようで別途有効にする必要があります
MockMVCを使っているのであればテスト用のMockMVCのオブジェクトを生成する際に.dispatchOptions(true)を指定します

this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).dispatchOptions(true).build();

これを実施しないとテスト時にOPTIONSメソッドが受け取れませんでした

最後に

OPTIONSメソッドはリソースがサポートしているメソッドの一覧を返却するために用意されたメソッドです
OPTIONSメソッドのリクエストのときにレスポンスボディを返却することは基本ないと思いますが、やりたい場合は今回紹介した方法で実現できると思います

2015年7月22日水曜日

開発合宿してみたいメモ

概要

  • 非日常的な環境で開発をすることで、おそろしく開発効率が上がるのではないか
  • 「仕事」として行く気はないので気軽に行こう
  • 成果のルールは決めない
  • 南国でやりたい

唯一のルール

  • 必ず最後に何をしたのか、していないのか、作ったのかなど「発表」をすること
  • 昼飯と晩飯はみんなで食べましょう

欲望メモ

  • 仕事はしたくない、とにかく自分がやりたいことをやってみよう
  • オフィスでない非日常的な環境で開発することで効率アップ(するかどうか)を体験してみる
  • あれ、オレリモートでも仕事できるじゃん
  • OSS、クローズドは問わない
  • ホテルとかじゃなくて、Airbnbとかでコテージとか借りてやりたい(ホテルでもいいと思うけど)
  • 食事、睡眠以外の時間は基本的にフリーでコーディング、場所も問わない、飯の時間は決めておくし、みんなで一緒に食う
  • フリー時間はコーディングすらしなくてもOK、遊んでもOK
  • コーディングスタイルは自由、ペアでもチームでも個人でもいい
  • メンバーは一応知人を中心に 3 - 5人、多すぎはダメ
  • コーディング中はみんなバラバラだと思うので連絡は Slack とかのチャットを使おうと思う
  • 1泊2日 or 2泊3日
  • あえて土日返上
  • 集合解散は最悪、現地集合 - 解散でもOK
  • 開発環境(ネットワーク、ディスプレイ)は知らん、自分で何とかする
  • 移動とかも知らん
  • 最後の発表はフリーフォーマット、特にテーマはなし
  • たぶん単発、定期的にやる気はないです
  • ぶっちゃけ自分が開発したいだけ

2015年7月16日木曜日

yum で Redis をインストール

概要

yum で Redis の最新版をインストール
バイナリをダウンロードしてインストールする方法はこちら

環境

  • CentOS 6.6 64bit

インストール方法

rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
yum clean all
yum install redis --enablerepo=remi
chkconfig redis on

20150715 時点では3.0.2-1というバージョンがインストールできました

2015年7月15日水曜日

NewRelic にサーバのメトリックを送信してみた

概要

NewRelic で Server のメトリック (CPU, Memory, I/O, Network) を送信する方法を紹介します
過去に紹介したものはアプリ単位で監視する方法を紹介しました
NewRelic ではサーバのメトリック情報だけを送信することもできるのでその方法を紹介します

環境

  • CentOS 6.3 64bit
  • newrelic-sysmond 2.1.0
  • NewRelic 2015/07/14時点

メトリック送信用エージェントのインストール

今回は CentOS のサーバなので yumコマンドでインストール可能です

rpm -Uvh http://yum.newrelic.com/pub/newrelic/el5/x86_64/newrelic-repo-5-3.noarch.rpm
yum install newrelic-sysmond

License Key の設定

License Key は RewRelic の WebUI 上で確認することができます
Account settings に License Key の記載があるのでそれを設定ファイルに記載します

vim /etc/newrelic/nrsysmond.cfg

license_key=xxxxxxxx

エージェントの起動

service newrelic-sysmond start

で起動してしばらくすると NewRelic の Servers に対象のサーバのメトリックが表示されると思います

Tips

上手く監視できなかった場合は、NewRelic とサーバ間の Outgoing の ACL を確認してみましょう
通信するべきIPとポートの情報は以下を参考にしてみたください
wget できなければいけないドメインやIPが記載されています
https://docs.newrelic.com/docs/apm/new-relic-apm/getting-started/networks#availability

動作確認

NewRelic の UI で確認してみましょう
左上のメニュー一覧から「Servers」を選択します
newrelic_choice_servers.png

サーバの一覧が選択されます
newrelic_list_servers.png

メトリックの詳細を見たい場合は対象のサーバをクリックすると見れます
newrelic_detail_metric.png

最後に

前に試した記憶ではnewrelic-sysmondも自動でインストールされて起動されていた記憶があったのですが、今回新規のサーバを追加したらnewrelic-sysmondがインストールされていなかったので別途インストールしてみました
メトリックを見るためだけならNewRelicはめっちゃ簡単です

2015年7月8日水曜日

Java で kill のシグナルを受け取ってみた

概要

Javaで kill の -HUP のシグナルを受け取れるみたいなので検証してみました

環境

Mac OS X 10.10.4
Eclipse Luna 4.4
Java 1.8.0_31

シグナルを受け付けるコードを作成

package test;

import java.util.Scanner;

public class Test {

    @SuppressWarnings("resource")
    public static void main(String[] args) throws InterruptedException {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> System.out.println("Run Shutdown Hook.")));
        System.out.println("Please send HUP signal.");
        while (true) {
            System.out.println("looping ...");
            Thread.sleep(5000);
        }
        // 以下のような入力を受け付ける処理でもOK
//      System.out.println("Please input.");
//      Scanner in = new Scanner(System.in);
//      String s = in.nextLine();
//      System.out.println(s);
    }
}

ポイントは1行で

Runtime.getRuntime().addShutdownHook(new Thread(() -> System.out.println("Run Shutdown Hook.")));

になります
上記の場合は HUP を受け取って終了する前にSystem.outを出力しています

動作を確認してみる

Eclipse 上で実行すると Eclipse の子プロセスとして実行されpidがわからないので java コマンドでターミナルから実行します
プロジェクトは普通の Java プロジェクトを想定しています

cd /path/to/project/bin
java test/Test

とすると無限ループがはじまります
この状態でpgrep javaでプロセス番号を調べてその番号を kill してみましょう

kill -HUP [process_number]

でこうすると無限ループが終了してSystem.outの内容が出力されます

$ java test/Test
Please send HUP signal.
looping ...
looping ...
Run Shutdown Hook.

とりあえずこれで Java 側でシグナルを受け取ることができました
addShutdownHookはメソッドもコールすることができるので別のメソッドをコールしてそっちの処理が終了するまでまた処理を続けることも可能です

最後に

これが何に使えるのかなというのを考えると

  • 無限ループに突入してしまった場合にHUP信号を外から送信して次の処理に進める
  • HUPしたタイミングで特定の処理(例えばロギング)を実行しその時の状況を把握する

とかとか
外部からシグナルを受け付けられる便利な機能なのでいろいろ考えられると思います

あと「java シグナル」とかで検索すると出てくる記事にsun.misc.Signalを使う方法が紹介されていますがどうやらsun.misc.Signalは非推奨もしくはなくなる可能性のあるクラスなので使わないほうがいいと思います

http://docs.oracle.com/javase/jp/6/api/java/lang/Runtime.html#addShutdownHook%28java.lang.Thread%29

2015年7月7日火曜日

Emacs で Mew を使って Gmail を受信してみた

概要

Emacs の mew というメールパッケージを使って Gmail を受信してみました
最新のMac (OS X) で試しています

環境

  • Mac OS X 10.10.4
  • stunnel 5.17
  • Emacs 24.4.1
  • Mew 6.6
  • Gmail 20150707時点

Mew のインストール

package.elを使ってインストールしました
package-list-packagesを起動して melpa の「mew 20150607.2316」を選択してインストールします
※20150707時点での最新の mew をインストールしているのでそれ以上のバージョンがあればそちらをインストールしてください

stunnel のインストール

stunnel は簡単に言えばSSL通信をするためのツールです
Homebrewを使ってインストールしました

brew install stunnel
/usr/local/bin/stunnel -version

証明書の設置

stunnel を使って Gmail と SSL 通信するのに利用します
stunnel のサイトで公開されている証明書をダウンロードして配置すればOKです

cd /var/tmp
wget http://www.mew.org/Release/certs-20110624.tar.gz
tar zvxf certs-20110624.tar.gz
mkdir ~/.certs
mv certs-20110624/* ~/.certs

GmailのIMAP設定

デフォルトではONになっています
ここの手順で確認することが可能です

Mewの設定を記載

.emacsでOKです
他の設定ファイルをloadしている場合はそのファイルでもOKです

; for configuration of mew
; Load stunnel
(setq mew-prog-ssl "/usr/local/bin/stunnel")
; User IMAP with Gmail for receiving a mail
(setq mew-proto "%")
(setq mew-imap-server "imap.gmail.com")
(setq mew-imap-ssl-port "993")
(setq mew-imap-user "your.account.name@gmail.com")
(setq mew-imap-auth  t)
(setq mew-imap-ssl t)
; User SMTP with Gmail for sending a mail
(setq mew-smtp-server "smtp.gmail.com")
(setq mew-smtp-ssl-port "465")
(setq mew-smtp-user "your.account.name@gmail.com")
(setq mew-smtp-auth t)
(setq mew-smtp-ssl t)

(setq mew-fcc "%Sent")
(setq mew-imap-trash-folder "%[Gmail]/ゴミ箱")
(setq mew-use-cached-passwd t)

変更する箇所は Gmail のアカウントを記載する部分です
「your.account.name」の部分を変更してください
その他が基本そのままでOKです
(setq mew-proto "%")とすることで mew を起動した際に受信フォルダに移動します
その他の値に関してここを検索するとどんな値なのかわかると思います

起動確認

emacs -e mew
とすると mew が立ち上がります
emacs を起動したあとでM-x mewでもOKです
立ち上がるとアカウントに対する認証が聞かれるのでGmailで使っているパスワードを入力します

問題なく認証が完了するとGmail上のメールデータが古い順に受信されます
初回起動時は全メールを取得するのでGmail上の受信メールが多い場合はダウンロードに時間がかかるかもしれません

デフォルトだと古い順に表示されるので新しい順に表示したい場合はバッファの最下部に移動してください

操作Tips

  • 終了方法
    Inbox内で「Q」とすることで終了させることができます
    メールの受信中に終了した場合は、mew 起動時に再度メールを受信してくれます

最後に

特にハマることなくできました
バージョンもだいぶ新しいのを使っているからでしょうか
ブラウザが使えない環境だと便利ですね
操作方法がわからなくなったら公式のマニュアルを読めばだいたいは解決すると思います

参考サイト

2015年7月6日月曜日

Heroku で Sinatra + Rack アプリを動かしてみた

概要

Sinatra で作成したアプリを Rack で動くようにして Heroku 上でも動作するようにしてみました
簡単にできたので紹介します
サンプルとして紹介するアプリはこちらです

環境

  • CentOS 6.6 64bit
  • Ruby 2.2.0p61
  • Sinatra 1.4.6
  • Rack 1.6.1
  • Heroku Toolbelt 3.39.1

Sinatra アプリの作成

何でもOKです
この辺を参考にすればあっさり作成できると思います
ruby app.rbで起動してポート4567でLISTENするアプリを作成できればOKです

Sinatra アプリを Rack で動作させる

config.ru の作成

config.rurackupという Rack のコマンドでアプリを起動させるために必要な起動ファイルです
以下のような感じで記載してください

require 'bundler'
Bundler.require

require './app'
run Sinatra::Application

requireしている./appの部分は作成した Sinatra アプリのファイル名を指定してください
これを作成したらrackupコマンドでアプリを起動できるようになります

rackup config.ru で起動できるはずです
またサンプルはbundlerでも動作するようになっています
bundler で動作させる場合はbundle exec rackup config.ruで起動できます

heroku へのデプロイ

herokuへのサービス登録は済ませておいてください
heroku-toolbeltのインストールがまだの場合は https://toolbelt.heroku.com/ を参考にインストールしてください
heroku-toolbeltがインストールできたらデプロイしていきます

デプロイは簡単です
作成した Rack アプリのディレクトリに移動して heroku にログインして push すればOKです

heroku login
heroku create
git push -u heroku master

とするだけでOKです
ログインは済んでいる場合は実行不要です

すでに登録済みのアプリに対してデプロイしたい場合はheroku createの代わりにgit remote add heroku https://git.heroku.com/APPNAME.gitとして heroku 上の git リポジトリを remote として追加します
APPNAMEの部分は既存のアプリ名を指定してください
heroku listで既存アプリ一覧を確認することができます

これで push に成功すれば rack アプリがデプロイされます

動作確認

push するとURLがターミナルに表示されると思うのでそこにアクセスしましょう
Mac等の環境でブラウザが使えるのであればheroku openでもOKです

サンプルを使っているのならばリクエスト情報をJsonでダンプしてくれるはずです

最後に

ポイントは config.ru で動作させるようにすることでした
Sinatra アプリとして動作する状況で push してもうまく動作しませんでした
heroku はどういうアプリなのかを自動で判断してアプリを起動します
Sinatra アプリの場合はそのままだと動作せず Rack アプリにすると動作するという話でした