2014年7月31日木曜日

指定したプロセスの実行経過時間を取得して秒変換するシェルスクリプト

何それって感じですがメモしておきます
OneLinerで記載しているのはzabbixのUserParameterで使いたかったから
絶対もっと簡単に取得する方法があるんだろうなと

TIME=`ps aux | grep PushToUsers | grep -v 'grep' | awk {'print $10'} | tail -n 1`; if [ -n "$TIME" ]; then echo $TIME | awk -F ':' '{if ($1 != 0) print ($1 * 60) + $2; else print $2;}'; else echo 0; fi;

OneLinerではなくフォーマットすると

TIME=`ps aux | grep hogehoge | grep -v 'grep' | awk {'print $10'} | tail -n 1`
if [ -n "$TIME" ]
then
  echo $TIME | awk -F ':' '{if ($1 != 0) print ($1 * 60) + $2; else print $2;}'
else
 echo 0
fi;

hogehogeの部分に監視したいプロセス名を指定します

2014年7月26日土曜日

Eclipse4.4(Luna)でTomcatPluginを動作させる方法

Keplerとかのバージョン時にEclipse MarketPlaceでインストールしているとLunaにバージョンアップした場合に Sysdeo Tomcat Launcher Plugin がうまく動作しませんでした
Sysdeo Tomcat Launcher Plugin の公式サイトに行ってみるとLuna版が配布されていたのでそのインストール方法を紹介します

  1. Eclipse 起動
  2. Help -> Install detail -> sysdeo で検索して検索して出てきたインストール済みのTomcat Pluginを選択して「Uninstall」をクリック
  3. Eclipse 一旦停止
  4. http://www.eclipsetotale.com/tomcatPlugin/tomcatPluginV331.zip をダウンロード、解凍
  5. 解凍してできた com.sysdeo.eclipse.tomcat_3.3.1.jar を /path/to/eclipse/dropins にコピー
  6. Eclipse 起動

でいけるはずです
一旦、前のバージョンをuninstallするのがポイントでしょうか
そのうちEclipse MarcketPlaceでLuna対応版が配布されるはずなのでそれを待ってUpdateしてもいいと思います

2014年7月25日金曜日

JenkinsのAPIを使ってジョブを作成してみた

P.S 20140826
curlを使ってジョブを登録する方法は下部の更におまけに追記しました



前回GET系のリクエストを試したので今回はPOST系を試してみました
Rubyを使ってジョブの登録を実施しています

実行するRubyスクリプトと同じディレクトリに下部に記載したconfig.xmlを配置して
実行してください

また、サンプルが job_list というファイルに記載されている登録したいジョブ名分
登録するようになっているので job_list というファイルも作成してください

#!/usr/bin/ruby
# -*- coding: utf-8 -*-
require 'net/http'
require 'json'

endpoint = "http://localhost:8080"

File.open("job_list").each {|f|
  path = "/createItem?name=" + f
  uri = URI.parse(endpoint + path)
  f = File.read("config.xml")
  
  header = {
    'Content-Type' =>'application/xml',
  }

  request = Net::HTTP::Post.new(uri.request_uri, header)
  request.body = f
  request.basic_auth 'username', 'password'
  
  #http = Net::HTTP::Proxy('proxy_host_name', '8080').new(uri.host, uri.port)
  http = Net::HTTP.new(uri.host, uri.port)
  http.start do |h|
    response = h.request(request)
    puts response.status
  end
}

<?xml version='1.0' encoding='UTF-8'?>
<project>
  <actions/>
  <description>this job is created by api</description>
  <keepdependencies>false</keepDependencies>
  <properties/>
  <scm class="hudson.scm.NullSCM"/>
  <canroam>true</canRoam>
  <disabled>false</disabled>
  <blockbuildwhendownstreambuilding>false</blockBuildWhenDownstreamBuilding>
  <blockbuildwhenupstreambuilding>false</blockBuildWhenUpstreamBuilding>
  <buildwrappers>
    <hudson.plugins.timestamper.TimestamperBuildWrapper plugin="timestamper@1.5.4"/>
  </buildWrappers>
</project>

■おまけ CURLでジョブをビルドする方法
curl -X POST --user username:password http://localhost:8080/job/test_job/build

■おまけ CURLでパラメータ付きジョブをビルドする方法
curl -X POST --user username:password "http://localhost:8080/job/test_job/buildWithParameters?key1=value&key2=value"

■更におまけ CURLでジョブを作成する方法
curl -X POST --user username:password --data-binary "@config.xml" -H "Content-Type: text/xml" "http://localhost:8080/createItem?name=job_name"

■参考サイト

2014年7月23日水曜日

Eclipse設定メモ

インストール

Eclipseの本家サイトからzipをダウンロードして適当な場所に配置して完了

設定

基本設定

Windows -> Preferences -> Run/Debug -> Console -> Limit console ouput のチェックを外す

キーバインド設定

Windows -> Preferences -> General -> Keys から以下を設定

Windows

  • Scheme を Emacs に変更する
  • Ctrl+h で検索して bind されている Ctrl+h を unbind して pevious で検索して Delete Previous に Ctrl+h を bind する
  • undo で検索して bind されている Ctrl+x, u を unbind して Ctrl+\ でbindする
  • Ctrl+f6 で検索して bind されている Next Editor を unbind して Ctrl+Tab を bind する
  • Previous Editor で検索して bind されている Ctrl+Shift+f6 を unbind して Ctrl+Shift+Tab をbind する
  • Ctrl+x, h で検索して SelectAll を unbind して Alt+a を bind する

Mac

設定する場合はKeyRemap4MacBookを終了してから実施すること

  • Scheme を Emacs に変更する
  • 「Open Search Dialog」を unbind、「Delete Previous」に Ctrl +h を bind する
  • 「Undo」の Command + z をunbind、Ctrl + \ で bind する
  • 「Next Editor」を unbind、Ctrl + tab で bind する
  • 「Previous Editor」を unbind、Shift + Ctrl + tab で bind する
  • 「Toggle Comment」を unbind、Ctrl + / で bind する
  • 「Correct Indentation」を unbind、Ctrl + i で bind する

Java設定

Preferences -> Java -> Installed JREs -> Add -> Standard VM -> JRE home

に以下を追加

  • Mac
    • /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home

プラグイン設定

Help -> Eclipse Marketplace
Help -> Install New Software
のどちらかでそれぞれインストール以下を設定

EGit

パースペクティブに Git の項目を追加する

Maven Integration for Eclipse(m2e)

インストールのみ、設定は特に無し

Android Development Tool for Eclipse

  • インストールしたandroid-sdkのパスを設定する
    • Mac ex : /usr/local/Cellar/android-sdk/24.0.1
  • Android SDK Managerを起動して最新版のBuild-toolsをダウンロードする(初回はダウンロードする量が多いので時間がかかる)
  • Intel x86 Emulator Accelerator (HAXM installer) をインストールする
    • SDK ManagerのExtraからインストール
    • インストーラがダウンロードされるので.dmgファイルを実行してインストール

      /usr/local/Cellar/android-sdk/24.0.1/extras/intel/Hardware_Accelerated_Execution_Manager/IntelHAXM_1.1.1_for_below_10_9.dmg

  • 開発用のAVDを作成する
  • appcompat_v7 の追加
    • 適当にAndroidプロジェクトを作成すればOK
  • google-play-services_lib の追加(Admob用)
    \path\to\adt\sdk\extras\google\google_play_services\libproject をプロジェクトとしてインポートするenter code here
    利用するプロジェクトを右クリックして Android -> Library -> Add -> google-play-services_lib を追加する
    google-play-services_lib が異なるドライブにあるとなぜかエラーになるので同一ドライブにコピーしてからインポートすること
  • プロジェクト側の設定

    Properties -> Android -> Add

    から google-play-services_lib を参照するように追加
    appcompat_v7が必要な場合はそれも追加

    • Android Private Libraries が読み込まれない場合
      libs 配下にあるandroid-support-v4.jarappcompat_v7/libs配下にあるandroid-support-v4.jarで上書きする
      既にjarがコミットしている場合にローカルとリポジトリ側でjarに差分があるために発生する

Eclipse Color Theme

  • Windows -> Preferences -> General -> Appearance -> Color Theme で Vibrant Inkを選択

TestNG for Eclipse

インストールのみ、設定は特に無し

Spket IDE

インストールのみ、設定は特に無し、インストールはこちら

Sysdeo Tomcat Launcher Plugin

インストールのみ、設定は特に無し
Eclipse MarcketPlaceからインストールできない場合はこちら

StepCounter

Marketplaceにはないのでjarをダウンロードしてdropinsに配置する

Grep Console

インストールのみ、設定は特に無し、インストールはこちら

Spring Tool Suite

インストールのみ、設定は特に無し、インストールはこちら

Tips

  • Ctrl + o でOutlineを表示できる

JenkinsのAPIを使ってみた

http://localhost:8080/ でジョブの一覧が見れるJenkinsで試した結果です
認証のユーザ情報は「Jenkinsのユーザーデータベース」を利用しています
簡単なGET系のリクエストのみとなります

環境
サーバ
Jenkins 1.517
CentOS 6.3

クライアント
Ruby 2.0.0

■CURLでリクエスト
curl --user username:password http://localhost:8080/api/json?pretty=true

■レスポンスサンプル
{
  "assignedLabels" : [
    {
      
    }
  ],
  "mode" : "NORMAL",
  "nodeDescription" : "the master Jenkins node",
  "nodeName" : "",
  "numExecutors" : 5,
  "description" : "description",
  "jobs" : [
    {
      "name" : "job001",
      "url" : "http://localhost:8080/job/job001/",
      "color" : "blue"
    },
    {
      "name" : "job002",
      "url" : "http://localhost:8080/job/job002/",
      "color" : "blue"
    }
  ],
  "overallLoad" : {
    
  },
  "primaryView" : {
    "name" : "view",
    "url" : "http://localhost:8080/"
  },
  "quietingDown" : false,
  "slaveAgentPort" : 0,
  "unlabeledLoad" : {
    
  },
  "useCrumbs" : false,
  "useSecurity" : true,
  "views" : [
    {
      "name" : "view",
      "url" : "http://localhost:8080/"
    },
    {
      "name" : "view02",
      "url" : "http://localhost:8080/view/view02/"
    }
  ]
}

■rubyから実施
#!/usr/bin/ruby
# -*- coding: utf-8 -*-
require 'open-uri'
require 'json'

uri = "http://localhost:8080/api/json?pretty=true"
auth = ['username', 'password']
#f = open(uri, {:http_basic_authentication => auth})
f = open(uri, {:http_basic_authentication => auth, :proxy => 'http://proxyname:8080/'})

json = JSON.parse(f.read)

json['jobs'].each { |i|
  p i['url']
}

ジョブのURL一覧がずらっと表示されます

特に認証を気にせずJSONでちゃちゃっと取得するだけならこれで十分そうですね
時間があればPOST系のリクエストも試してみたい

2014年7月22日火曜日

Cygwin設定メモ

インストール

Cygwinの公式サイトからインストーラをダウンロードし実行
setup.exe時にインストールする追加パッケージは以下

  • wget, wget-debuginfo
  • vim, vim-common

設定

基本設定

ルートパス変更

vim /etc/passwd

/home/username
↓
/cygdrive/c/Users/username

※ P.S 20150929
/etc/passwd と /etc/group がない場合は以下のコマンドで生成してください

mkpasswd -l > /etc/passwd
mkgroup  -l > /etc/group

cd / && ln -nfs /cygdrive/c/
cd / && ln -nfs /cygdrive/e/

SSH用の設定ファイル作成

mkdir .ssh
touch .ssh/config
vim .ssh/config

ServerAliveInterval 15

作業用ディレクトリ作成

mkdir -p ~/data/repo
mkdir -p ~/Documents/work

bashの設定ファイル作成 

touch .bashrc
vim .bashrc

#!/bin/sh

alias ls='ls --show-control-chars --color'
alias tmuxclean='rm -rf /tmp/tmux'
alias ifconfig='ipconfig | nkf -w'
alias tailf='tail -f'
alias ps='ps -efW'

if [[ "$OSTYPE" =~ "cygwin" ]];then
  # Chocolatey
  alias choco="echo -ne '\n' | cmd /c choco"
  alias cinst='cmd /c cinst'
  alias cup='cmd /c cup'
  alias cuninst='cmd /c cuninst'
fi

touch .bash_profile
vim .bash_profile

#!/bin/sh

if [ -f $HOME/.bashrc ]
then
  source $HOME/.bashrc
fi

.bashrc と .bash_profile の改行コードをLF、文字コードをUTF-8にする

bash補完時のignore-case設定

vim /etc/inputrc

set completion-ignore-case on

カーソルの色を変更する

左上のアイコンから -> Options -> Looks -> Colours -> Cursor でCyanぽい色に変更する

apt-cyg

wget http://apt-cyg.googlecode.com/svn/trunk/apt-cyg
wget https://raw.githubusercontent.com/transcode-open/apt-cyg/master/apt-cyg
mv apt-cyg /usr/bin
chmod +x /usr/bin/apt-cyg

apt-cyg install openssh automake gcc-core libevent2.0_5 libevent-devel ncurses libncurses-devel pkg-config make vim git procps emacs util-linux
apt-cyg install ruby subversion
apt-cyg install libgmp-devel libcrypt-devel curl

gem install bundler

※P.S 20150929
Cygwin のバージョンが2以上の場合は apt-cyg のソースコードを直接編集する必要があります
http://kakakikikeke.blogspot.jp/2015/09/md5-sum-did-not-match-exiting.html

emacs

mkdir -p ~/.emacs.d/backup
mkdir -p ~/.emacs.d/site-lisp
touch ~/.emacs.d/site-lisp/init.el
vim .emacs

package.el

cd ~/.emacs.d/site-lisp
wget http://repo.or.cz/w/emacs.git/blob_plain/1a0a666f941c99882093d7bd08ced15033bc3f0c:/lisp/emacs-lisp/package.el
emacs ~/.emacs.d/site-lisp/init.el

(require 'package)
(add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/"))
(add-to-list 'package-archives  '("marmalade" . "http://marmalade-repo.org/packages/"))
(package-initialize)

package.el が 404 で見つからない場合は以下から取得する
http://kakakikikeke.blogspot.jp/2015/10/emacs23-package-el.html

package-install でインストールするパッケージ一覧

  • パッケージのインストール方法
    M-x package-install [package-name]
    or
    M-x package-list-packages
    iでインストールするパッケージを選択してxでインストールを実行する
  • require
    • anything
    • anything-config
    • anything-match-plugin
    • auto-complete
    • flycheck
      • gem install ruby-lint
      • 各言語ごとに必要なsyntax checkerはインストールすること
    • twittering-mode
    • php-mode
    • markdown-mode
    • highlight-symbol
  • options
    • flymake
    • w3m
    • Navi2ch
  • emacs ~/.emacs.d/site-lisp/init.el
;;; .init.el --- init config emacs

;;; Commentary:
;;;; Author: kakakikikeke
;;;; Version: 0.1

;;; Code:
; for package.el
(require 'package)
(add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/"))
(add-to-list 'package-archives  '("marmalade" . "http://marmalade-repo.org/packages/"))
(package-initialize)

; for anything
(require 'anything-startup)
(keyboard-translate ?\C-h ?\C-?)
(add-to-list 'anything-sources 'anything-c-source-emacs-commands)

; for auto-complete
(require 'auto-complete-config)
(add-to-list 'ac-dictionary-directories "~/.emacs.d/elpa/auto-complete-20140618.2217/dict")
(ac-config-default)
(setq ac-use-menu-map t)
(define-key ac-menu-map "\C-n" 'ac-next)
(define-key ac-menu-map "\C-p" 'ac-previous)

; for flymake
(add-hook 'after-init-hook #'global-flycheck-mode)

; for twittering-mode
(require 'twittering-mode)
;(setq twittering-proxy-use t)
(setq twittering-use-master-password t)

; highlight-symbol
(require 'highlight-symbol)
(setq highlight-symbol-colors
      '(
        "DarkOrange" "DodgerBlue1" "DeepPink1"
        "goldenrod3" "orchid2" "chartreuse3"
        "yellow3" "firebrick1" "green2"
        "IndianRed3" "SeaGreen3" "turquoise1"
        "SlateBlue2" "medium orchid" "sea green"
        ))
(global-set-key "\C-x," 'highlight-symbol-at-point)

;;; init.el ends here

nkf

http://sourceforge.jp/projects/nkf/downloads/59912/nkf-2.1.3.tar.gz/ からブラウザを使ってダウンロード
cd ~/Downloads
tar zvxf nkf-2.1.3.tar.gz
cd nkf-2.1.3
make && make install

tmux

http://sourceforge.net/projects/tmux/files/tmux/tmux-1.9/tmux-1.9a.tar.gz/download?use_mirror=jaist からブラウザを使ってダウロード
https://tmux.github.io/ の Download から最新版をダウンロードしてください

tar zvxf tmux-1.9a.tar.gz
cd tmux-1.9a
./configure && make && make install

touch ~/.tmux.conf
emacs ~/.tmux.conf
これを記載する

git

git config –global color.ui true

vim ~/.gitconfig

[alias]
    tr = log --graph --pretty='format:%C(yellow)%h%Creset %s %Cgreen(%an)%Creset %Cred%d%Creset'

percol

apt-cyg install python-setuptools
easy_install https://pypi.python.org/packages/source/p/pip/pip-1.4.1.tar.gz
pip install percol
mkdir ~/.percol.d
touch ~/.percol.d/rc.py
emacs ~/.percol.d/rc.py

percol.view.PROMPT  = ur"<bold><yellow>Let's percol ></yellow></bold> %q"

# Emacs like
percol.import_keymap({
    "C-h" : lambda percol: percol.command.delete_backward_char(),
    "C-d" : lambda percol: percol.command.delete_forward_char(),
    "C-k" : lambda percol: percol.command.kill_end_of_line(),
    "C-y" : lambda percol: percol.command.yank(),
    "C-t" : lambda percol: percol.command.transpose_chars(),
    "C-a" : lambda percol: percol.command.beginning_of_line(),
    "C-e" : lambda percol: percol.command.end_of_line(),
    "C-b" : lambda percol: percol.command.backward_char(),
    "C-f" : lambda percol: percol.command.forward_char(),
    "M-f" : lambda percol: percol.command.forward_word(),
    "M-b" : lambda percol: percol.command.backward_word(),
    "M-d" : lambda percol: percol.command.delete_forward_word(),
    "M-h" : lambda percol: percol.command.delete_backward_word(),
    "C-n" : lambda percol: percol.command.select_next(),
    "C-p" : lambda percol: percol.command.select_previous(),
    "C-v" : lambda percol: percol.command.select_next_page(),
    "M-v" : lambda percol: percol.command.select_previous_page(),
    "M-<" : lambda percol: percol.command.select_top(),
    "M->" : lambda percol: percol.command.select_bottom(),
    "C-m" : lambda percol: percol.finish(),
    "C-j" : lambda percol: percol.finish(),
    "C-g" : lambda percol: percol.cancel(),
})

other

ant

wget http://ftp.kddilabs.jp/infosystems/apache//ant/binaries/apache-ant-1.9.4-bin.tar.gz
tar zvxf apache-ant-1.9.4-bin.tar.gz
mv apache-ant-1.9.4 /usr/bin/
cd /usr/bin
ln -nfs /usr/bin/apache-ant-1.9.4/bin/ant ant

maven

wget http://ftp.kddilabs.jp/infosystems/apache/maven/maven-3/3.2.2/binaries/apache-maven-3.2.2-bin.tar.gz
tar zvxf apache-maven-3.2.2-bin.tar.gz
mv apache-maven-3.2.2 /usr/bin
cd /usr/bin
ln -nfs /usr/bin/apache-maven-3.2.2/bin/mvn mvn

jq

http://kakakikikeke.blogspot.com/2015/03/cygwin-jq.html

Tips

uname -a でcygwinのバージョンを確認することができる
ps -efW でWindowsで動作しているプロセスの一覧も確認できる

2014年7月18日金曜日

コマンドラインからAmazonアソシエイトの広告リンクを作成してみた

AmazonアソシエイトのHTMLリンクを1商品分だけコマンドで簡単に生成できたらいいなーと思って作ってみました
Rubyの「amazon-ecs」というGemを使っています

■環境
Mac OS X 10.8.5
Ruby 2.1.2p95
Gem 2.2.2
amazon-ecs 2.2.5

■設定
gem install amazon-ecs
gem install launchy

■ソースコード
touch call_amazon_api.rb

# -*- coding: utf-8 -*-
require 'amazon/ecs'
require 'launchy'

if ARGV.length != 1
then 
  p "Please input search keyword using the argument"
  exit 1
end
keyword = ARGV[0];

amazon_tracking_id = "Please input your amazon asociate tracking id"
access_key = "Please input your aws access_key or specified evn ACCESS_KEY at executing"
secret_key = "Please input your aws access_key or specified evn SECRET_KEY at executing"

if ENV["ACCESS_KEY"]
then
  access_key = ENV["ACCESS_KEY"]
end

if ENV["SECRET_KEY"]
then
  secret_key = ENV["SECRET_KEY"]
end

Amazon::Ecs.options = {
  :associate_tag => amazon_tracking_id,
  :AWS_access_key_id => access_key,
  :AWS_secret_key => secret_key
}

res = Amazon::Ecs.item_search(keyword, :response_group => 'Small, ItemAttributes, Images', :search_index => 'All', :country => 'jp')

#puts res.marshal_dump

res.items.each do |item|
  element = item.get_element('ItemAttributes')
  
  data = {
    :asin => item.get('ASIN'), 
    :title => element.get("Title"), 
    :page_url => "http://www.amazon.co.jp/dp/#{item.get('ASIN')}?tag=#{amazon_tracking_id}", 
    :isbn => element.get("ISBN"), 
    :author => element.get_array("Author").join(", "), 
    :product_group => element.get("ProductGroup"), 
    :manufacturer => element.get("Manufacturer"), 
    :publication_date => element.get("PublicationDate"), 
    :small_image => item.get_hash("SmallImage"), 
    :medium_image => item.get_hash("MediumImage"), 
    :large_image => item.get_hash("LargeImage")
  }
  image_info = data[:medium_image]
  html_file = "index.html"
  file_path = File.dirname(__FILE__) + "/" + html_file
  f = File::open(File.dirname(__FILE__) + "/" + html_file, "w+");
  f.puts(
         "<a href=\"#{data[:page_url]}\" target=\"_blank\"><table style=\"border-style: solid;\">" + 
         "<tr>" +
         "<td><img src=\"#{image_info['URL']}\" /></td>" +
         "<td><div>#{data[:title]}</div><div style=\"margin-top: 5px; font-size: 11px;\">#{data[:manufacturer]}</div><div style=\"font-size: 11px;\">#{data[:author]}</div></td>" +
         "</tr>" +
         "</table></a>"
         );
  f.rewind
  puts f.read
  f.close();
  Launchy.open(file_path)
  break;
end

まず「amazon_tracking_id」に自分のAmazonアソシエイト用のtrackingIDを指定します
次に「access_key」と「secret_key」ですが、これは直接ソースを編集してもいいし、ruby実行時の環境変数(ACCESS_KEY, SECRET_KEY)で指定しても大丈夫です

各自で設定する箇所は以上であとは ruby call_amazon_api.rb Java と実行すればOKです
Javaと指定している部分はAmazonで検索するキーワードで好きなキーワードを指定することができます
日本語もきっと使用できます

処理の流れとしてはキーワードを元にランキングを取得し1位の情報だけを取り出してWebサイトで表示するためのHTMLを作成します
作成したHTMLはターミナルの標準出力に表示されるので使いたい場合はコピペして使ってください
また、作成すると同時にHTML情報をデフォルトのブラウザで表示するようにしているので、HTMLのサンプルを作成することもできます

■サンプルレスポンス
<a href="http://www.amazon.co.jp/dp/4844330861?tag=kakakikikeke-22" target="_blank">
  <table style="border-style: solid;">
    <tr>
      <td>
        <img src="http://ecx.images-amazon.com/images/I/51fRtwXdWLL._SL160_.jpg" />
      </td>
      <td>
        <div>スッキリわかるJava入門</div>
        <div style="margin-top: 5px; font-size: 11px;">インプレスジャパン</div>
        <div style="font-size: 11px;">中山 清喬, 国本 大悟</div>
      </td>
    </tr>
  </table>
</a>


Web上での表示は以下の通り
スッキリわかるJava入門
インプレスジャパン
中山 清喬, 国本 大悟


ちょっとした商品を紹介するときには役にたつかなと思います

■参考リンク
Amazon-ECS APIリファレンス
ソースコード

進め方としては基本はAPIリファレンスベースに進めるといいと思う
APIのリクエストパラメータはruby内部でcamelizeしているので
SearchIndex -> :search_index
みたいな感じで変換してパラメータを設定することができる
レスポンスに関してはget_elementメソッドを使ってXMLの要素名を指定することでオブジェクトを取得してそこからgetなどでString情報を抜き出すことができる

2014年7月17日木曜日

pipのインストール方法

・easy_installでインストール
easy_install pip
※easy_installのインストール手順はこちら

・インストールスクリプトからインストール
wget https://bootstrap.pypa.io/get-pip.py
python get-pip.py

2014年7月15日火曜日

BloggerAPIv3をrubyから使ってみた

■環境
Mac OS X 10.8.5
Ruby 2.1.2p95
Gem 2.2.2

■事前準備
  • Googleアカウントの作成
  • Google Developer Consoleでプロジェクトの作成
  • RubyおよびGemのインストール
※ここは説明を省略します

■作成したプロジェクトが持つアクセスキーに紐づくリダイレクトURLを設定する
何かややこしい書き方をしていますが、BloggerAPIv3は認証時にOAuth2を用いるためリダイレクトURLを設定する必要があります

  1. https://code.google.com/apis/console/b/0/?noredirect#project:[project_number]:access にアクセス
  2. [project_number]にはDevelopers Consoleで確認できるプロジェクトの番号を入力してください
  3. 左メニュー上部に現在のプロジェクトを切り替えるプルダウンがあるので作成したプロジェクトに切り替え
  4. 左メニューの「API Access」を選択
  5. 「Client ID for web applications」用のアクセスキーが存在するか確認します、ない場合は「Create another client ID」から新規にアクセスキーを作成
  6. 新規アクセスキー作成時に「Redirect URIs」を「http://localhost:9292」に設定
  7. 作成が完了したら一覧に戻り作成したアクセスキーに「Redirect URIs」が設定されているか確認

ここでリダイレクトURLに localhost:9292 を設定しているのは、使用しているgoogle-api-clientのgemが勝手にコールバックしてくれるURLになります
アプリ側(google-api-client を使用した ruby アプリ)から指定するリダイレクトURLとDevelopers Console側に登録したアクセスキーが持つリダイレクトURLは同一である必要があるためです
またこの作業はURLを見てもわかりますが旧Developer Consoleで実施する必要があります

以下のような感じになっていればOKです

■Google Developers Consoleから認証用のjsonファイルを取得する
  1. https://console.developers.google.com/ にアクセス
  2. Googleアカウントでログイン後、プロジェクトの一覧から作成したプロジェクトを選択
  3. 左メニューからCredentialsを選択
  4. OAuthの「Download JSON」をクリックし適当な位置にダウンロード
  5. ダウンロード後ファイル名をclient_secrets.jsonに変更、サンプルソースコードと同じディレクトリに保存

ここでダウンロードしたjsonファイルを元にgoogle-api-clientが勝手にOAuth2認証を実施してくれます

以下の箇所からダウンロードするイメージです

■google-api-clientのGemインストール
gem install google-api-client

■サンプルソースコード
先ほどダウンロードした認証用のJsonファイルがと同じ階層に以下のサンプルコードを配置してください

# -*- coding: utf-8 -*-
require 'google/api_client'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/installed_app'
require 'json'

blog_id = "Please input your blogger_id"

client = Google::APIClient.new(
  :application_name => 'Sample Blogger API App',
  :application_version => '1.0.0'
)
blogger = client.discovered_api('blogger', 'v3')

# この処理でダウンロードしたアクセスキーが記載されたJsonファイルを読み込む
client_secrets = Google::APIClient::ClientSecrets.load

flow = Google::APIClient::InstalledAppFlow.new(
  :client_id => client_secrets.client_id,
  :client_secret => client_secrets.client_secret,
  :scope => ['https://www.googleapis.com/auth/blogger']
)
# アプリを認証許可するまでここでwaitする
client.authorization = flow.authorize

# APIを実行する
result = client.execute(
  :api_method => blogger.posts.list,
  :parameters => { 'blogId' => blog_id }
)

# return Google::APIClient::Schema::Blogger::V3::PostList
# puts result.data.class
# puts result.data.methods
# puts result.data.to_json

json = JSON.parse(result.data.to_json)
json['items'].each do |item|
  puts "id : " + item['id']
  puts "title : " + item['title']
  puts "content : " + item['content']
end

blog_id = "Please input your blogger_id"
の部分に自分のbloggerのIDを入力してください
blog_idはbloggerの管理UIにログインしてURLに表示される番号を入力してください

ruby test_blogger_api.rb

と実行するとリダイレクトURLに設定したlocalhost:9292のページが表示されアプリからのアクセス承認を求められます
その後、ターミナルに戻るとポストの一覧が結果がされていると思います
1回の取得で最大10件しか取得できないので次のページを取得する場合はレスポンスのobjectをページネートして次の10件を取得してください
(たしか、resultオブジェクトにページネートできるメソッドが実装されていたと思います)

以上です
ポイントはOAuth2.0を使っているのでプロジェクトに作成するアクセスキーにちゃんとRedirect URLを設定するところでしょうか
あとはRubyのリファレンスが少ないのでmethodsで使えるメソッド名を確認したり参考サイトにも紹介しているAPIExplorerで実際のJsonレスポンスを見てレスポンスオブジェクトへのアクセス方法を自分調べる必要がありました

■参考サイト
google-api-client本家サイト
https://developers.google.com/api-client-library/ruby/start/get_started?hl=ja

Google API Explorer
ここを参考にしてexecuteするリクエストのパラメータ等は調べられると思います
https://developers.google.com/apis-explorer/#p/blogger/v3/

2014年7月11日金曜日

Eclipseを使ってJavaのソースコードの行数をカウントする方法

StepCounterというオープンソースのEclipseプラグインを使って簡単に取得できたので紹介します

■環境
Windows7 64bit
Eclipse 4.3 Kepler

■インストール
https://github.com/takezoe/stepcounter/releases から最新のjarファイルをダウンロードします
自分は「jp.sf.amateras.stepcounter_3.0.3.201404150124.jar」が最新版だったので左記のjarをダウンロードしました

ダウンロードしたらEclipseのpluginsフォルダに配置します
「/path/to/eclipse/plugins/jp.sf.amateras.stepcounter_3.0.3.201404150124.jar」となればOKです

Eclipseを起動(もしくは再起動)します

問題なくEclipseが起動すれば、インストールはこれで完了です

■使ってみる
Eclipseが起動したらプロジェクトを右クリックして「ステップカウンタ」->「ステップ数をカウント」と選択します


すると「カウント結果」というビューで結果を表示してくれます
Javaの実行している行数の他に空行やコメントの数もちゃんとカウントしてくれるので実行ステップだけが正確に取得できます


あとビューのどこかで右クリックするとExcel形式にエクスポートすることも可能です

classファイルやjarファイル内はカウントできないようです(他にもカウントをサポートしていないファイル形式がある)

とりあえずこれで簡単に実行ステップ数を算出することができるようになりました
Eclipseのプロジェクトとしてすでにインポートしている場合はこれで簡単に算出できます
まだプロジェクトとしてインポートしていない場合でインポートするのが面倒という場合にはEclipseのプラグインでなくjarを直接コマンドで実行することでステップをカウントしてくれる機能もあるので
Eclipseが嫌いな方、インポートが面倒な方はそれを利用するといいかと思いました

■参考サイト

2014年7月8日火曜日

AmazonSQSにMessageAttributeという機能が追加になっていたので試してみた

簡単に説明するとメッセージに対してメタ情報を付与できるサービスです
key - value 形式で属性を付与することができます
また value に対して型定義することができサーバ側で型のバリデーションを実施してくれます
どんな感じで使用できるのか試してみました

■環境
AmazonSQS
CentOS release 5.10 (Final)
クライアントツール java-signature

■試してみる
1. テスト用のキューを作成する
今回テストするためのキューを作成します
VisibilityTimeout は 0 で作成します

java -jar target/CallAws-jar-with-dependencies.jar -e sqs.ap-northeast-1.amazonaws.com -a CreateQueue -b '{"QueueName":"attributeTest","Attribute.1.Name":"VisibilityTimeout","Attribute.1.Value":0}' -u

2. まずはSendMessageしてみる
早速、Attributeを付与したMessageを送信してみます
Attributeは key - value 形式で登録でき、valueに型を指定することができます

以下のメッセージ情報を送信してみます
  • MessageBody・・・This is a test message
  • MessageAttribute・・・env
  • MessageValue・・・dev
  • MessageDataType・・・String
※QueueUrlに含まれるアカウントIDは念のため伏せております
java -jar target/CallAws-jar-with-dependencies.jar -e sqs.ap-northeast-1.amazonaws.com -a SendMessage -b '{"QueueUrl":"http://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxxxx/attributeTest","MessageAttribute.1.Name":"env","MessageAttribute.1.Value.StringValue":"dev","MessageAttribute.1.Value.DataType":"String","MessageBody":"This is a test message"}' -u
サンプルではAttributeは1つしか登録していませんが複数付与することも可能です
その場合は「MessageAttribute.1.Name」の「1」の部分を「2」にしてリクエストのボディに追加すればOKです
追加できる数に上限はありませんが、メッセージ全体で256KB以内でなければいけないという制約はあります

送信したメッセージをコンソールで見ると以下のような感じになります
※複数のAttributeが設定してある場合のイメージです


型はデフォルトで String, Number, Binary が提供されており型にあったValueが設定されていないとエラーとなります
Binary型の送信は試していませんが基本はプログラム上でメディアデータなどをbyte配列に変換し送信する感じかと思います
また独自の型を作成することもでき、その場合は「Number.int」「Binary.jpg」のように「.(ドット)」区切りで指定します

3. RendMessageで確認してみる
送信したメッセージを受信してみます
ReceiveMessage 時のリクエストに取得する MessageAttribute パラメータを指定します
「All」を指定するとメッセージに付与されているすべての Attribute 情報と MessageBody を取得することができます
Attribute には key の情報を指定するので今回は「env」と指定しています

java -jar target/CallAws-jar-with-dependencies.jar -e sqs.ap-northeast-1.amazonaws.com -a ReceiveMessage -b '{"QueueUrl":"http://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxxxx/attributeTest", "MessageAttributeName":"env"}' -u --format-xml

存在しない Attribute を指定するとエラーとはならず Attribute が含まれないレスポンスが返ってきます

レスポンスのサンプルを以下に記載します
<?xml version="1.0" encoding="UTF-8"?><ReceiveMessageResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/">
  <ReceiveMessageResult>
    <Message>
      <Body>This is a test message</Body>
      <MD5OfBody>fafb00f5732ab283681e124bf8747ed1</MD5OfBody>
      <ReceiptHandle>cOJv9qrD9XLVlpsfwYn3xbqoRwvfbdaQLvbKbLf00e/k6ciYz083Jqz15w+g0xpfpL3IZw32hD0mrLllzyQfgkZTT83Um5PLuE5qxjYeH6qhCZz6UBZXSD+J7ti4XbZYJ9qLk9EEoXffMmSogLbouqy4S/fiX6fnFxflHVcyItgHRtjk5TgDk6DJb831h7N2HtUohH/gWyI3d69S1Sc+RRYw++c0H50QatUG2T1GTqPxRDyb5jR6d6b1BiQXw2BV5u3qdGMF7re3RIQrx81kTlPLJIHHcmHa77JUGzBTldXwNNJotDOPSA==</ReceiptHandle>
      <MessageAttribute>
        <Name>env</Name>
        <Value>
          <DataType>String</DataType>
          <StringValue>dev</StringValue>
        </Value>
      </MessageAttribute>
      <MessageId>f3001768-2bd2-488e-8613-8fffaf66c410</MessageId>
      <MD5OfMessageAttributes>2c1856f51437cf57b1a473e4bee30521</MD5OfMessageAttributes>
    </Message>
  </ReceiveMessageResult>
  <ResponseMetadata>
    <RequestId>8184b4a6-f345-584e-a677-f8927c83f696</RequestId>
  </ResponseMetadata>
</ReceiveMessageResponse>
MessageAttribute タグ内に設定した Attribute 情報が付与されていることがわかります

■ユースケースを考える
とりあえず設定する方法と取得する方法はわかりましたが、では一体これはどんなときに使えるのでしょうか

Amazonの公式のBlogPostにもとしてユースケースが載っていました
この例だとモバイルアプリを想定しており、ガソリンの料金をシェアするアプリのようです
ガソリンの料金をシェアするみたいな感じで、アプリからメッセージを送信すると位置情報とガソリン料金が付与されたメッセージが送信されます
すると、サーバサイドでメッセージが受信されメッセージの Attribute に位置情報とガソリンの料金が入っていた場合に
その情報を AWS の DynamoDB に突っ込み、DynamoDB の GeoLibraryという機能を使うことで、そのガソリンスタンドの近くにいる人に最安のガソリンスタンドの情報をプッシュすることができるみたいなことを記載していました(間違っていたらすいません。。)

使い方はいろいろ考えられますが、メッセージがどんな属性なのかというのをメッセージ本文の情報とは別で管理できるので
メッセージを処理する、所謂ワーカー側は Attribute の情報だけをみて処理を判断することができます
また型も指定してあるので、取得した段階で必要な型にキャストされていることが保証されているのでワーカー側の実装も簡単になるのかなと思います

メッセージの Attribute 機能が実装される以前でもメッセージ本文にJSONなりなんなりでメタ情報を付与すれば同様のことすることはできるのかと思いますが
SQSの仕様として明確に「Attribute が key - value で指定できる」とすることでメッセージのデータ構造体というか作りが綺麗になるので
利用者からするとメッセージの管理がしやすくなるのかなと思います

最近は Backend As a Service といったモバイル向けのクラウドサービスも登場していることからその辺りを想定した機能を実装したのかもしれません
バイナリデータを指定できる部分とかはまさにモバイル向けなのかなと思いました

■参考URL

2014年7月6日日曜日

Invalid implementation version between Ant core and Ant optional tasks.

CentOS上のantを1.9.4にバージョンアップしようとしたら以下のエラーが発生した

[root@localhost tmp]# ant
Invalid implementation version between Ant core and Ant optional tasks.
 core    : 1.8.1 in file:/root/.m2/repository/org/apache/ant/ant/1.8.1/ant-1.8.1.jar
 optional: null in file:/usr/local/ant/lib/ant.jar

まず原因(の予想)ですが、実行しているantのバージョンは1.9.4だけど、実行のために必要なjarファイルのバージョンは1.8.1だよ
と言って怒られているのが原因かなと思います

パスを見ると .m2 内の jar ファイルのバージョンが古いと言って怒られており、.m2 なので一件関係ないような気がするのですが
今回の場合(というか私の場合).m2 配下に存在する jar ファイルをすべて CLASS_PATH に追加しています

ant のソースコードを見たわけではないので詳しくはわからないですが、おそらく ant は CLASS_PATH 上に存在する ant用の jar ファイルを優先的に使うようになっており
その jar と実行しようとしている ant のバージョンが異なっているので実行に失敗していると思われます
(すいません、念押ししますがこの辺りはかなり推測が含まれます。。。)

解決する方法としては
  • ant の1.8.1を使う
  • .m2 (CLASS_PATH 上)に ant-1.9.4 の jar を配置する

で解決できるかと思います
そして、今回は下の方法で解決できましたので紹介します

1. jar をインストールするための maven プロジェクトを作成
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-quickstart -DgroupId=com.sample.bbb -DartifactId=bbb
2. pom.xml のdependencies タグ内にに以下を追記
<dependency>
  <groupId>org.apache.ant</groupId>
  <artifactId>ant</artifactId>
  <version>1.9.4</version>
</dependency>
3. jar のダウンロード
mvn clean install
4. .m2 上に jar がダウンロードされることを確認する

その後 新しく追加された jar を CLASS_PATH の設定に追加するために再ログインしました
(自分の場合は再ログインすることで CLASS_PATH が更新される仕組みを .bashrc に記載しているため)
といった感じで今回は解決できました
正直バットノウハウ過ぎますが、念のためメモしておきます

2014年7月5日土曜日

Phingを使ってaws-adk-phpをビルドしてみた

■環境
CentOS release 5.10 (Final)
PHP 5.3.3
Pear 1.9.4 インストール方法
Composer インストール方法

■Phingインストール
pear channel-discover pear.phing.info
Adding Channel "pear.phing.info" succeeded
Discovery of channel "pear.phing.info" succeeded

pear install --alldeps phing/phing
Unknown remote channel: pear.phpunit.de
Unknown remote channel: pear.phpunit.de
WARNING: "pear/PEAR_PackageFileManager" is deprecated in favor of "pear/PEAR_PackageFileManager2"
Unknown remote channel: pear.pdepend.org
Unknown remote channel: pear.phpmd.org
Unknown remote channel: pear.phpunit.de
Unknown remote channel: pear.phpunit.de
Unknown remote channel: pear.phpdoc.org
Did not download optional dependencies: phing/phingdocs, pear/VersionControl_SVN, pear/VersionControl_Git, channel://pear.phpunit.de/PHPUnit, channel://pear.phpunit.de/PHP_CodeCoverage, pecl/Xdebug, pear/PEAR_PackageFileManager, pear/Services_Amazon_S3, channel://pear.pdepend.org/PHP_Depend, channel://pear.phpmd.org/PHP_PMD, channel://pear.phpunit.de/phpcpd, channel://pear.phpunit.de/phploc, channel://pear.phpdoc.org/phpDocumentor, pear/PHP_CodeSniffer, pear/Net_Growl, use --alldeps to download automatically
phing/phing can optionally use package "phing/phingdocs" (version >= 2.8.1)
phing/phing can optionally use package "pear/VersionControl_SVN" (version >= 0.4.0)
phing/phing can optionally use package "pear/VersionControl_Git" (version >= 0.4.3)
phing/phing can optionally use package "channel://pear.phpunit.de/PHPUnit" (version >= 3.6.0)
phing/phing can optionally use package "channel://pear.phpunit.de/PHP_CodeCoverage" (version >= 1.1.0)
phing/phing can optionally use package "pecl/Xdebug" (version >= 2.0.5)
phing/phing can optionally use package "pear/PEAR_PackageFileManager" (version >= 1.5.2)
phing/phing can optionally use package "pear/Services_Amazon_S3" (version >= 0.3.1)
phing/phing can optionally use package "channel://pear.pdepend.org/PHP_Depend" (version >= 0.10.0)
phing/phing can optionally use package "channel://pear.phpmd.org/PHP_PMD" (version >= 1.1.0)
phing/phing can optionally use package "channel://pear.phpunit.de/phpcpd" (version >= 1.3.3)
phing/phing can optionally use package "channel://pear.phpunit.de/phploc" (version >= 1.6.4)
phing/phing can optionally use package "channel://pear.phpdoc.org/phpDocumentor" (version >= 2.0.0b7)
phing/phing can optionally use package "pear/PHP_CodeSniffer" (version >= 1.5.0)
phing/phing can optionally use package "pear/Net_Growl" (version >= 2.6.0)
downloading phing-2.8.1.tgz ...
Starting to download phing-2.8.1.tgz (483,377 bytes)
.................................................................................................done: 483,377 bytes
install ok: channel://pear.phing.info/phing-2.8.1

pear list -c PEAR.PHING.INFO
INSTALLED PACKAGES, CHANNEL PEAR.PHING.INFO:
============================================
PACKAGE VERSION STATE
phing   2.8.1   stable

■aws-sdk-php のダウンロード
git clone https://github.com/aws/aws-sdk-php.git

■必要なライブラリのインストール(composer)
cd aws-sdk-php
※composer.js が存在することを確認します

composer install
Loading composer repositories with package information
Installing dependencies (including require-dev)
  - Installing symfony/event-dispatcher (v2.5.0)
    Downloading: 100%

  - Installing guzzle/guzzle (v3.9.1)
    Loading from cache

  - Installing doctrine/cache (v1.3.0)
    Downloading: 100%

  - Installing psr/log (1.0.0)
    Downloading: 100%

  - Installing monolog/monolog (1.4.1)
    Downloading: 100%

  - Installing sebastian/version (1.0.3)
    Downloading: 100%

  - Installing sebastian/exporter (1.0.1)
    Downloading: 100%

  - Installing sebastian/environment (1.0.0)
    Downloading: 100%

  - Installing sebastian/diff (1.1.0)
    Downloading: 100%

  - Installing sebastian/comparator (1.0.0)
    Downloading: 100%

  - Installing symfony/yaml (v2.5.0)
    Downloading: 100%

  - Installing phpunit/php-text-template (1.2.0)
    Downloading: 100%

  - Installing phpunit/phpunit-mock-objects (2.1.5)
    Downloading: 100%

  - Installing phpunit/php-timer (1.0.5)
    Downloading: 100%

  - Installing phpunit/php-token-stream (1.2.2)
    Downloading: 100%

  - Installing phpunit/php-file-iterator (1.3.4)
    Downloading: 100%

  - Installing phpunit/php-code-coverage (2.0.9)
    Downloading: 100%

  - Installing phpunit/phpunit (4.1.3)
    Downloading: 100%

  - Installing symfony/class-loader (v2.5.0)
    Downloading: 100%

symfony/event-dispatcher suggests installing symfony/dependency-injection ()
symfony/event-dispatcher suggests installing symfony/http-kernel ()
monolog/monolog suggests installing mlehner/gelf-php (Allow sending log messages to a GrayLog2 server)
monolog/monolog suggests installing raven/raven (Allow sending log messages to a Sentry server)
monolog/monolog suggests installing doctrine/couchdb (Allow sending log messages to a CouchDB server)
monolog/monolog suggests installing ext-amqp (Allow sending log messages to an AMQP server (1.0+ required))
monolog/monolog suggests installing ext-mongo (Allow sending log messages to a MongoDB server)
phpunit/php-code-coverage suggests installing ext-xdebug (>=2.2.1)
phpunit/phpunit suggests installing phpunit/php-invoker (~1.1)
Writing lock file
Generating autoload files

■aws-sdk-phpのビルド
cd aws-sdk-php
※build.xml が存在することを確認します

phing
※デフォルトだとUnitTestだけが実行されます
Buildfile: /var/tmp/aws-sdk-php/build.xml

aws-sdk-for-php > test-init:

     [copy] phpunit.xml.dist omitted, is up to date
     [copy] phpunit.functional.xml.dist omitted, is up to date
     [copy] test_services.json.dist omitted, is up to date

aws-sdk-for-php > test:

PHPUnit 4.1.3 by Sebastian Bergmann.

Configuration read from /var/tmp/aws-sdk-php/phpunit.xml

...SSS.......................................................F.  63 / 856 (  7%)
....................................................S.......... 126 / 856 ( 14%)
............................................................... 189 / 856 ( 22%)
............................................................... 252 / 856 ( 29%)
............................................................... 315 / 856 ( 36%)
............................................................... 378 / 856 ( 44%)
............................................................... 441 / 856 ( 51%)
............................................................... 504 / 856 ( 58%)
............................................................... 567 / 856 ( 66%)
............................................................... 630 / 856 ( 73%)
..................................PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to alloate 491520 bytes) in /var/tmp/aws-sdk-php/src/Aws/S3/Resources/s3-2006-03-01.php on line 1330

BUILD FINISHED

Total time: 3.9861 seconds
メモリが少ないと言われてテストが途中で失敗してしまいました
今回はスルーして先に進みます

phing build
※ライブラリとして配布できるpharファイルを作成します
Buildfile: /var/tmp/aws-sdk-php/build.xml

aws-sdk-for-php > phplint:


aws-sdk-for-php > clean:

   [delete] Directory /var/tmp/aws-sdk-php/build/artifacts does not exist or is not a directory.

aws-sdk-for-php > test-init:

     [copy] phpunit.xml.dist omitted, is up to date
     [copy] phpunit.functional.xml.dist omitted, is up to date
     [copy] test_services.json.dist omitted, is up to date

aws-sdk-for-php > prepare:

    [mkdir] Created dir: /var/tmp/aws-sdk-php/build/artifacts
    [mkdir] Created dir: /var/tmp/aws-sdk-php/build/artifacts/logs

aws-sdk-for-php > test:

PHPUnit 4.1.3 by Sebastian Bergmann.

Configuration read from /var/tmp/aws-sdk-php/phpunit.xml

...SSS.......................................................F.  63 / 856 (  7%)
....................................................S.......... 126 / 856 ( 14%)
............................................................... 189 / 856 ( 22%)
............................................................... 252 / 856 ( 29%)
............................................................... 315 / 856 ( 36%)
............................................................... 378 / 856 ( 44%)
............................................................... 441 / 856 ( 51%)
............................................................... 504 / 856 ( 58%)
............................................................... 567 / 856 ( 66%)
............................................................... 630 / 856 ( 73%)
..................................PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 491520 bytes) in /var/tmp/aws-sdk-php/src/Aws/S3/Resources/s3-2006-03-01.php on line 1330

aws-sdk-for-php > create-staging:

    [mkdir] Created dir: /var/tmp/aws-sdk-php/build/artifacts/staging
    [mkdir] Created dir: /var/tmp/aws-sdk-php/build/artifacts/staging/Aws
    [mkdir] Created dir: /var/tmp/aws-sdk-php/build/artifacts/staging/Guzzle
    [mkdir] Created dir: /var/tmp/aws-sdk-php/build/artifacts/staging/Doctrine/Common/Cache
    [mkdir] Created dir: /var/tmp/aws-sdk-php/build/artifacts/staging/Symfony
    [mkdir] Created dir: /var/tmp/aws-sdk-php/build/artifacts/staging/Monolog
     [copy] Copying 1 file to /var/tmp/aws-sdk-php/build/artifacts/staging
     [copy] Copying 925 files to /var/tmp/aws-sdk-php/build/artifacts/staging
     [copy] Copying 1 file to /var/tmp/aws-sdk-php/build/artifacts/staging/Aws
     [copy] Copying 1 file to /var/tmp/aws-sdk-php/build/artifacts/staging/Aws
     [copy] Copying 18 files to /var/tmp/aws-sdk-php/build/artifacts/staging
     [copy] Copying 91 files to /var/tmp/aws-sdk-php/build/artifacts/staging
     [copy] Copying 234 files to /var/tmp/aws-sdk-php/build/artifacts/staging
     [copy] Copying 45 files to /var/tmp/aws-sdk-php/build/artifacts/staging
     [copy] Copying 9 files to /var/tmp/aws-sdk-php/build/artifacts/staging
     [copy] Copying 17 files to /var/tmp/aws-sdk-php/build/artifacts/staging

aws-sdk-for-php > phar:

[pharpackage] Building package: /var/tmp/aws-sdk-php/build/aws.phar

aws-sdk-for-php > build:


BUILD FINISHED

Total time: 13.3099 seconds
先にテストが実行された後に phar ファイルが作成されます

SDKの改修をするのであれば
ソース改修 -> phing build -> phar 作成 -> テスト
といった流れで改修して行く感じかと思います

■作成したpharファイルの実行
cd aws-sdk-php/build
emacs pharTest.php
<?php
require './aws.phar';

use Aws\Sqs\SqsClient;

$client = SqsClient::factory(array(
  'key'    => 'your access key',
  'secret' => 'your secret access key',
  'region' => 'ap-northeast-1'
));
$result = $client->listQueues(array());
var_dump($result);
?>

php pharTest.php
でキューの東京リージョンにあるキューの一覧が取得できるかと思います

以上です
aws-sdk-php はオープンソースなのでバグがあったときはこれで修正してプルリクエストでも送ってあげるといいと思います
ちなみに「phing zip」として実行すると phar ファイルの代わりに配布可能な zip ファイルを作成してくれます

■参考サイト

2014年7月4日金曜日

Windows + MavenでSeleniumのUIテスト

■環境
Windows7 64bit
Java 1.7.0_25
Maven 3.1.1
Selenium API 2.42.2
Firefox 30.0

■プロジェクト作成
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-quickstart -DgroupId=com.sample.selenium -DartifactId=selenium_test
※maven-archetype-quickstart を使います

バージョンを入力し内容の確認に答えればOKです(そのままエンターでOKです)

■pom.xml編集
作成されたpom.xmlを以下の用に編集してください
Seleniumのライブラリを使用する定義を追加します

<dependency>
  <groupId>org.seleniumhq.selenium</groupId>
  <artifactId>selenium-api</artifactId>
  <version>2.42.2</version>
</dependency>
<dependency>
  <groupId>org.seleniumhq.selenium</groupId>
  <artifactId>selenium-java</artifactId>
  <version>2.42.2</version>
</dependency>

mvn clean install
するとライブラリがダウンロードされてきます

ついでにMaven経由でJavaを実行するためのプラグインもインストールします
<build>
  <plugins>
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>exec-maven-plugin</artifactId>
      <version>1.2.1</version>
      <configuration>
        <mainClass>com.sample.selenium.App</mainClass>
      </configuration>
    </plugin>
  </plugins>
</build>

■サンプルテストコード
emacs src/main/java/com/sample/selenium/App.java

package com.sample.selenium;

import com.thoughtworks.selenium.*;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.*;

public class App {

  private static int SLEEP_TIME = 5000;
  
  public static void main(String args[]) throws Exception {
    new App().updateRanking();
  }

  public void updateRanking() throws Exception {
    FirefoxProfile profile = new FirefoxProfile();
    profile.setAcceptUntrustedCertificates(true);
    FirefoxDriver driver = new FirefoxDriver(profile);

    driver.get("http://fc2.com/login.php?ref=blog");
    driver.findElement(By.id("id")).click();
    Thread.sleep(SLEEP_TIME);
    driver.findElement(By.id("id")).sendKeys("username");
    Thread.sleep(SLEEP_TIME);
    driver.findElement(By.id("pass")).click();
    Thread.sleep(SLEEP_TIME);
    driver.findElement(By.id("pass")).sendKeys("password");
    Thread.sleep(SLEEP_TIME);
    driver.findElement(By.name("image")).click();
    Thread.sleep(SLEEP_TIME);
    driver.findElement(By.linkText("プラグインの設定")).click();
    Thread.sleep(SLEEP_TIME);
    driver.findElement(By.xpath("(//a[contains(text(),'詳細')])[2]")).click();
    Thread.sleep(SLEEP_TIME);
    driver.findElement(By.linkText("【HTMLの編集】")).click();
    Thread.sleep(SLEEP_TIME);
    driver.findElement(By.name("value1")).clear();
    Thread.sleep(SLEEP_TIME);
    driver.findElement(By.name("value1")).sendKeys("test contents for plugins in side bar");
    Thread.sleep(SLEEP_TIME);
    driver.findElement(By.cssSelector("input.submitAddButton")).click();
    Thread.sleep(SLEEP_TIME);
    driver.quit();
  }

}

完全にプライベートなソースコードですが
fc2 blogにログインしてサイドバーの内容を更新するサンプルです
XML-RPCでは記事本文しか自動更新できないのでサイドバー等はUIを使って変更するしかありません

mvn clean compile
でソースをコンパイルします
M2_HOME等のmavenの設定がうまくできていれば問題なくコンパイルできるかと思います

■サンプルの実行
mvn clean compile exec:java

とコマンドプロンプト上で実行するとFirefoxが立ち上がりブラウザが自動で動きはじまると思います
ネットワーク等が重く動作が安定しない場合はSLEEP_TIMEを5000から10000(10秒)等に変更して試してみてください

以上です
MavenからSeleniumを動作させることができました
SeleniumIDEでJavaのソースコードをExportする場合はJUnitかTestNGのどちらかでテスト形式であることが前提なので
必ずテストコードにする必要がありましたが、それを書き換えて通常のJavaプロジェクトとして動作させてみました
また、今回はWindows環境で実施しましたが、Seleniumのテストを実施する場合どうしてもGUI環境が必要になるので
仕方なくWindows環境を使用しました
Mac または X のあるLinux環境でも問題なく動作すると思います

■参考サイト

■Tips
maven の場合は依存関係をいい感じの解決してくれたのですが、
maven を使わない場合はselenium系の jar 以外に Guava や Json のライブラリで40個以上必要になるみたいです
http://stackoverflow.com/questions/9699997/selenium-2-webdriver-noclassdeffounderrors

なので通常のJavaプロジェクトの場合はselenium-server-standalone-2.39.0.jarを使ってあげるといろいろな jar をインストールしなくて済むので楽です

2014年7月3日木曜日

redisのデータをWebで見れるphpRedisAdminをインストール

■環境
CentOS release 5.10 (Final)
redis 2.6.3
PHP 5.3.3
Composer 3251f9f1aa997479fff78905841e22beacfbe37b
Apache 2.2.3

■インストール
redisのインストール(Chefでインストール)
Composerのインストール
PHPおよびApacheのインストールはyumで済ませました

cd /var/www/html
composer create-project -s dev erik-dubbelboer/php-redis-admin phpRedisAdmin
※DocumentRoot直下に展開しているのでDocumentRootが異なる場合は展開場所を適宜変更してください

composer をインストールしたくない場合は
cd /var/www/html
git clone https://github.com/ErikDubbelboer/phpRedisAdmin.git
cd phpRedisAdmin
git clone https://github.com/nrk/predis.git vendor
でもインストールできます

■動作確認
redis-server と httpd を起動します
起動しているポートがデフォルトの6379であれば以下に問い合わせるだけで redis 内の情報にアクセスできます

http://localhost/phpRedisAdmin/?overview

■参考サイト

2014年7月2日水曜日

Windows7にredisをインストールしてみた

redis公式ではWindows用のインストーラやバイナリは配布しておらず
MSOpenTechというGithubのアカウントがWindows用のredisをオープンソースで開発してくれています
https://github.com/MSOpenTech/redis
今回はそれをforkしてできたバイナリのインストーラを利用したいと思います

■環境
Windows7 64bit
redis for Windows 2.8.9

■インストール
  1. https://github.com/downloads/rgl/redis/redis-2.4.6-setup-64-bit.exe をダウンロード
  2. インストーラを実行してインストール
  3. C:\Program Files\Redis に移動して「redis-server.exe」を実行
  4. cmd /c redis-server.exe で起動する
  5. スタート -> すべてのプログラム -> Redis -> Redis Client を起動
  6. Redisに接続できることを確認

一応これでWindows上でredisを使えるようになりました
ローカル検証用には十分かなと思います

2014年7月1日火曜日

Windowsで80番ポートがすでに使われていたので調べてみた

原因は「Skype.exe」でした
以下対策です

  1. コマンドプロンプトを開いて「netstat -aon | grep 0.0:80」で動作しているプロセス番号を確認
  2. コマンドプロンプトを開いて「tasklist.exe | grep [proc_num]」で動作しているプロセス名を取得
  3. ここで原因がSkype.exeだとわかる
  4. Skypeを開いて「ツール」->「設定」->「詳細」->「接続」->「追加の受信接続にポート80と443を使用」のチェックを外す
  5. Skype.exeを再起動(タスクマネージャからでもSkypeを直接再起動してもOK)

これで80番とついでに443番ポートが開放されます