JJUG CCC 2014 Spring

1401546452* Attended Sessions & Memo

R1-1 Java 8 for Java EE 7/6
  1. Java SE8を導入したら真っ先にやりたいところ
    1. Date and Time API
    2. Type Annotation (nullチェックロジック不要になる)
    3. Lambda expression
      1. 順序を守らせるためには forEachOrdered !!!
  2. MW対応状況 (#10)

http://www.slideshare.net/iwasakihirofumi/future-of-java-ee-with-java-se-8

H-2 Javaトラブルに備えよう
  1. 備えは大事

http://www.slideshare.net/agetsuma/java-34815905

R5-3 TDD BootCamp in JJUG CCC -レガシーコード対策ハンズオン-
  1. どれだけテストするか? --> どれだけ不安か?次第
  2. テストファーストが効率よいところ
    1. try & error するところ (独自API, ロジックを使うところ)
    2. 計算するところ
    3. 今回の修正範囲。おれのせいじゃない、を最初に担保する
R1-6 最近の Java Web 開発 (2014 春)

https://speakerdeck.com/monzou/spa-development

AND/OR Search

This is new feature of slim3 (framework for GAE/J) Version 1.0.16.
http://code.google.com/p/slim3/issues/detail?id=113

This is my sample.

CompositeCriterion keywordFilter = new CompositeCriterion(ITEM_META, CompositeFilterOperator.OR,
		new CompositeCriterion(ITEM_META, CompositeFilterOperator.AND, ITEM_META.itemID.startsWith(keyword)),
		new CompositeCriterion(ITEM_META, CompositeFilterOperator.AND, ITEM_META.itemName.startsWith(keyword)));

S3QueryResultList<Item> list = Datastore.query(ITEM_META).filter(keywordFilter).limit(limit).asQueryResultList();

I should be glad to be of any service to you.

They empowers me. I will empower him and you!

個人事業主の友達からバックオフィス業務をITで効率化したいと相談されたのが去年の12月。
それじゃーちょっとやってみようということで、朝カフェとか帰りの電車の中で作ってみました。

今回作ったシステムの機能

  1. システム管理系
    1. 各種マスタ (主に利用ユーザー登録など)
    2. Google Spread Sheet からのマスタデータ・インポート機能 (API)
  2. 日常業務系
    1. 商品検索
    2. 見積管理
    3. 発注管理
  3. メンテナンス業務
    1. 商品マスタ
    2. メーカーマスタ


設計時の注意点・工夫

GAEの特性や制約内に収まるようにすることが全てです。今回のシステム化対象に特化した仕様になりましたが、横点してビジネスをやるわけでもないので、これでOKかと!ポイントは

  1. データサイズが大きくならないように
    1. ライフサイクルを考える
    2. 更新時のロック対象範囲が狭まるように
  2. データcreate 時に参照情報、集計情報を書きこむ
    1. 書込みが遅いため。逆に読込みは速い
    2. マスタデータの更新頻度や業務によって考える

最後に

10年前だったら、自鯖(もはや死後!)をどうするか?回線は?とか、の話があったので敷居の高い話でした。
が、今回はそういったプラットフォームはGoogleさん任せ(一定量まで無料)で、業務ロジックやUIの開発だけに集中できました。
いやぁー有難い!

ということで、何かネタを貰うか思いついたら、またやってみようと思います。

BitNami Redmine Stack に TestLink を追加

環境

Windows Server 2008 SP2 (64bit)
BitNami Redmine Stack 1.3.0

今回追加したもの

PHP 5.3.10 (VC9 x86 Thread Safe) ※Microsoft 2008 C++ Runtime が別途必要です
TestLink 1.7.5 + TestLinkCnvMacro v571

手順概略

  1. PHPインストール (含む httpd.conf 修正その1)
  2. php.ini 修正
  3. TestLink 1.7.5 本体解凍
  4. TestLinkCnvMacro v571 解凍・上書き
  5. httpd.conf 修正 その2
  6. サービス再起動
  7. TestLink 初回セットアップ

1. PHPインストール

参照… PHP本家 http://php.net/manual/ja/install.windows.apache2.php
ダウンロード … http://windows.php.net/download/
今回は C:/PHP/ にインストールしました。
注意点としては 「すべてのバックスラッシュは、前向きスラッシュに変換する」です
インストーラーのウィザードでhttpd.conf を指定するところがあって、この時に、下記項目が追加されます(httpd.conf 修正その1)。末尾に追加されるので嫌な人は適切な場所に移動しましょう。

#PHPApache 2.x ハンドラとして使う設定
LoadModule php5_module "c:/php/php5apache2.dll"
AddHandler application/x-httpd-php .php

# php.ini へのパス
PHPIniDir "C:/PHP"

PHPフォルダにある php5ts.dll を Windows の system32 フォルダにコピーします。

あとで使うフォルダを作成しておきます
C:/PHP/tmp

2. php.ini 修正

修正箇所の抜粋
default_port は $BITNAMI_ROOT/mysql/my.ini の port の値を参照します。

max_execution_time = 120
extension=php_curl.dll
extension=php_gd2.dll
extension=php_mbstring.dll
extension=php_mysql.dll
extension=php_mysqli.dll
extension=php_openssl.dll
extension_dir = "C:/PHP/ext"
enable_dl = On

[MySQL]
mysql.default_port = 3306
mysql.default_socket= "C:/Program Files/BitNami Redmine
Stack/mysql/tmp/mysql.sock"

[Session]
session.save_path = "C:/PHP/tmp"
session.gc_maxlifetime = 2880

[MySQLi] myphpadmin 用
mysqli.default_port = 3306
mysqli.default_socket= "C:\Program Files\BitNami Redmine
Stack/mysql/tmp/mysql.sock"

3. TestLink 1.7.5 本体解凍

apps フォルダの下に “testlink” フォルダを作成し、その下に “htdocs” と “conf” の2つのフォルダを作成します。
C:\Program Files\BitNami Redmine Stack\apps\testlink\htdocs
C:\Program Files\BitNami Redmine Stack\apps\testlink\conf

htdocs フォルダの下に testlink のファイルを全て置きます。

conf フォルダの下に testlink.conf ファイルを新規作成し、以下のように記述します。

Alias /testlink "C:/Program Files/BitNami Redmine Stack/apps/testlink/htdocs"

AllowOverride None
Options None
Order allow,deny
Allow from all

4. TestLinkCnvMacro v571 解凍・上書き

使わない場合は、ここの話はスルーしてください
testlink フォルダの基点をそろえて上書きします

5. httpd.conf 修正その2

Apache2 で php が動作するように、さらに追加


DirectoryIndex index.html index.php

httpd.conf の最後の方にある Include に追加

Include "C:/Program Files/BitNami Redmine Stack/apps/testlink/conf/testlink.conf"

6. サービス再起動

7. TestLink 初回セットアップ + TestLinkCnvMacro分 再セットアップ

”http:///testlink” にアクセスし、初回セットアップを行ってください
途中で入力するMySQLの管理者名とパスワードは、Redmineのmy.ini に書かれている値です
TestLinkCnvMacro を追加で入れる場合は同様のウィザードを再度こなします。

Goodbye Trac, Hello Redmine!

TracLightning3.1.1 から Redmine 1.3.0 へ引っ越した時のメモです。
Redmineを使いたいけど、今までのTracのデータがあるしなぁ、というかたの参考になれば幸いです。

年度末のサービスインを控えた、忙しいこの時期に何でこんなことをやったのか? の理由は→こちら

目次

  1. Redmine セットアップ・追加プラグインなど
  2. SVNリポジトリ作成、設定など
  3. データ移行事前
  4. データ移行当日
  5. データ移行事後

Redmine本体インストール・追加プラグインなど

Redmine本体

bitnami-redmine-*.*.*-*-windows-installerをbitnami公式サイトから入手、インストールしました。特に注意を要することもなく、すんなりインストールできました。

今回はWindows Servernにインストールしたので、Windows ファイアウォールにて下記プログラムの接続を許可しました。

  1. httpd.exe
  2. svn.exe
ライブラリ FasterCSV

別でいれるredmine_importerで使うライブラリだそう。インストールできてるような、できてないような、ちょっと不安な感じです。

  1. モジュール取得 (今回は fastercsv-1.5.1.gem をチョイス)
  2. フォルダを作って
    • mkdir C:\Program Files\BitNami Redmine Stack\apps\redmine\vendor\gems\fastercsv-1.5.1
  3. インストール
    • gem install fastercsv-1.5.1.gem --local
redmine_importer

CSV形式のチケットデータを取り込みます。Tracのチケットデータを移行する時に使いました。
チケットを大量登録する時にも使えそうです。(何度か試しましたが、更新は上手くいきませんでした・・・ ^^;;)

インストールはこちらを参考にさせていただきました

  1. モジュール取得
  2. 解凍してできたディレクトリをC:\Program Files\BitNami Redmine Stack\apps\redmine\vendor\pluginsにコピー
  3. "redmine_importer"にリネーム
  4. インストール
    • cd C:\Program Files\BitNami Redmine Stack\apps\redmine\
    • rake db:migrate_plugins RAILS_ENV=production
  5. Redmine再起動
パーキングロットチャート
  1. モジュール取得
  2. 解凍してできたディレクトリを、C:\Program Files\BitNami Redmine Stack\apps\redmine\vendor\plugins
  3. "parking_lot_chart"にリネーム
  4. Redmineを再起動
WorkTimeプラグイン

おすすめです!朝会の昨日実績報告で使ってます。

  1. モジュール取得
  2. インストール
    • cd C:\Program Files\BitNami Redmine Stack\apps\redmine
    • rake db:migrate_plugins RAILS_ENV=production

SVNリポジトリ作成、設定など

BitNami Redmine Stack には最初から Subversion が付いているので、インストールは不要です

(1) リポジトリの作成

C:\Program Files\BitNami Redmine Stack\use_redmine.bat
svnadmin create C:\repos\dev

(2) システム環境変数のPath登録

C:\Program Files\BitNami Redmine Stack\subversion\bin

(3) モジュールコピー

C:\Program Files\BitNami Redmine Stack\subversion\binの以下2つを 〜\apache2\modules へコピー

  • mod_authz_svn.so
  • mod_dav_svn.so
(4) モジュール有効化

httpd.conf。サーバの『Administrator』ユーザじゃないと編集できませんでした。

  1. コメントIN
    • LoadModule dav_module modules/mod_dav.so
    • LoadModule dav_fs_module modules/mod_dav_fs.so
    • LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
    • LoadModule ldap_module modules/mod_ldap.so
  2. 追記
    • LoadModule authz_svn_module modules/mod_authz_svn.so
    • LoadModule dav_svn_module modules/mod_dav_svn.so
(5) ロケーション定義を追加

httpd.conf。合わせてActiveDirectoryの特定のグループのユーザーにのみアクセスを許可

  • SVNPath: リポジトリへのフルパスをセット
  • Require ldap-group: ActiveDirectoryの特定のグループのユーザーにのみアクセスを許可
  • AuthzSVNAccessFile : アクセス制御の定義を行うファイルを指定します。

サンプルです


 DAV svn
 SVNPath C:/repos/dev
 AuthType Basic
 AuthBasicProvider ldap
 AuthName "SVN Repo Authentication(dev)"
 AuthzLDAPAuthoritative off
 AuthLDAPURL "適宜"
 AuthLDAPBindDN 適宜
 AuthLDAPBindPassword 適宜
 AuthLDAPGroupAttribute member
 AuthLDAPGroupAttributeIsDN on
 Require ldap-group 適宜
 Require valid-user
 AuthzSVNAccessFile C:/repos/AuthzSVNAccess_dev.conf

★AuthzSVNAccess_dev.confサンプル。※参考サイトはこちら

[groups]
devmembers = yamakai,yamamoto
[/]
 * = r
[/trunk]
hoge = rw
@devmembers = rw
(6) 環境変数の変更を反映させるためにWindowsを再起動
(7) 確認

"http://localhost/dev/"でブラウザからリビジョン0が見れることを確認する

データ移行 事前

こちらで詳細を書きましたが、開発チームとは別に導入案件のSVNリポジトリを作りました。

  • 案件毎の空SVNリポジトリ事前作成 (trunk, branches, tags)
  • 案件毎リポジトリ SVN権限設定 (Apache > httpd.conf)
  • 案件毎のtrunkを各案件のメンバーのPCにチェックアウトしておいてもらう(移行後はこちらにデータが入ってくる)
  • 作業開始前バックアップ

データ移行 当日

(1) SVNリポジトリデータ
  1. @旧サーバ。まず今のリポジトリをダンプ。
    • svnadmin dump /path/to/svn/repos > repos.dump
  2. ダンプしたものを新サーバへもっていく
  3. @新サーバ。まずリポジトリを作成して、旧サーバからもってきたダンプを流し込むだけ。
    • svnadmin create /path/to/svn/repos
    • svnadmin load /path/to/svn/repos < repos.dump
(2) 過去チケット
  • csvインポートプラグインを使いました。TracからエクスポートしたチケットデータをRedmine用に整形する時のポイントは以下のとおり
    • 日付フォーマットは yyyy-mm-dd
    • ユーザ名を設定するところは、名前でなくてRedmine上のユーザIDを使う
    • チケットステータス文言を変更。closed → 終了、new → 新規 など
    • 改行コードをLFで初期化。混ざりまくりでお手上げ状態だったので、改行コードを削除しました。
  • 添付チケットについてはチケット移行完了後に、個別で貼り付け

Tracからチケットデータをエクスポートするときに使ったクエリのサンプル

SELECT
  p.value AS __color__,
 (CASE status 
    WHEN 'closed' THEN 'color: #777; background: #ddd; border-color: #ccc;'
    ELSE 
      (CASE owner WHEN '$USER' THEN 'font-weight: bold' END)
  END) AS __style__,
  id        AS ticket,
  t.type    AS 'tracker',
  summary   AS 'title',
  status    AS 'status',
  priority  AS 'priority',
  owner     AS '担当者',
  c6.value  AS '開始日',   
  c7.value  AS '期日', 
  description AS '_description',  
  milestone AS '対象バージョン',
  reporter  AS '登録者',
  time      AS '登録日付',
  c10.value AS 'Rev', 
  keywords  AS 'Keywords',
  c1.value  AS '検出日', 
  c5.value  AS '検出局面', 
  c4.value  AS '完了日', 
  c3.value  AS '確認者', 
  c2.value  AS '確認日', 
  c11.value AS 'TestCases',
  c12.value AS 'TroubleReason',
  resolution
FROM
  ticket t
  LEFT OUTER JOIN enum p ON p.name = t.priority AND p.type='priority'
  --修正リビジョン→Rev
  LEFT OUTER JOIN ticket_custom c10 ON (t.id = c10.ticket AND c10.name = 'rev')
  --テストケースNo→TestCases
  LEFT OUTER JOIN ticket_custom c11 ON (t.id = c11.ticket AND c11.name = 'testcase_id')
  --開始予定日→開始日
  LEFT OUTER JOIN ticket_custom c6  ON (t.id = c6.ticket  AND c6.name  = 'due_assign')
  --完了予定日→期日
  LEFT OUTER JOIN ticket_custom c7  ON (t.id = c7.ticket  AND c7.name  = 'due_close')
  --障害原因分類→TroubleReason
  LEFT OUTER JOIN ticket_custom c12 ON (t.id = c12.ticket AND c12.name = 'trouble_reason')
  --検出日
  LEFT OUTER JOIN ticket_custom c1  ON (t.id = c1.ticket  AND c1.name  = 'detected_date')
  --検出局面
  LEFT OUTER JOIN ticket_custom c5  ON (t.id = c5.ticket  AND c5.name  = 'detection_phaset')
  --完了日
  LEFT OUTER JOIN ticket_custom c4  ON (t.id = c4.ticket  AND c4.name  = 'complete')
  --確認者
  LEFT OUTER JOIN ticket_custom c3  ON (t.id = c3.ticket  AND c3.name  = 'close_checker')
  --確認日
  LEFT OUTER JOIN ticket_custom c2  ON (t.id = c2.ticket  AND c2.name  = 'close_check_date')
ORDER BY
  t.id

Tracからチケットのコメント履歴をエクスポートするときに使ったクエリのサンプル

select
 ticket,
 newvalue
from
 ticket_change c
where
 field = 'comment'
 and newvalue not like ''
order by ticket, time


Tracから抜きしたデータをExcelのマクロを使ってRedmine用に整形し、出力します。項目値変換はlookup関数がお勧めです。

Option Explicit
Sub WRITE_REDMINE_TICKET()
    Const cnsTITLE = "出力処理"
    Const cnsFILTER = "テキストファイル (*.csv;*.*),*.csv;*.*"
    Dim xlAPP As Application      ' Applicationオブジェクト
    Dim intFF As Integer            ' FreeFile値
    Dim strFILENAME As String   ' OPENするファイル名(フルパス)
    Dim strREC As String           ' 書き出すレコード内容
    Dim GYO As Long                ' 収容するセルの行
    Dim GYOMAX As Long          ' データが収容された最終行
    Dim lngREC As Long             ' レコード件数カウンタ

    ' Applicationオブジェクト取得
    Set xlAPP = Application

    ' 「名前を付けて保存」のフォームでファイル名の指定を受ける
    xlAPP.StatusBar = "出力するファイル名を指定して下さい。"
    strFILENAME = xlAPP.GetSaveAsFilename(InitialFileName:="IKOU_TICKETS.csv", _
        FileFilter:=cnsFILTER, Title:=cnsTITLE)

    ' キャンセルされた場合は以降の処理は行なわない
    If StrConv(strFILENAME, vbUpperCase) = "FALSE" Then Exit Sub

    ' 収容最終行の判定(Excel認知の最終行から上に向かってデータがある行を探す)
    GYOMAX = Cells.SpecialCells(xlCellTypeLastCell).Row
    Do While Cells(GYOMAX, 1).Value = "0"
        GYOMAX = GYOMAX - 1
    Loop
    If GYOMAX < 2 Then
        xlAPP.StatusBar = False
        MsgBox "データを2行目から入力してから起動して下さい。", , cnsTITLE
        Exit Sub
    End If

    ' FreeFile値の取得(以降この値で入出力する)
    intFF = FreeFile
    ' 指定ファイルをOPEN(出力モード)
    Open strFILENAME For Output As #intFF
    ' 1行目から開始
    GYO = 1
    ' 最終行まで繰り返す
    Do Until GYO > GYOMAX
        ' N列内容をレコードにセット(先頭は3行目)
        strREC = Cells(GYO, 1).Value & "," & _
                 Cells(GYO, 2).Value & "," & _
                 """" & Cells(GYO, 3).Value & """" & "," & _
                 Cells(GYO, 4).Value & "," & _
                 Cells(GYO, 5).Value & "," & _
                 Cells(GYO, 6).Value & "," & _
                 Replace(Cells(GYO, 7).Value, "/", "-") & "," & _
                 Replace(Cells(GYO, 8).Value, "/", "-") & "," & _
                 """" & Cells(GYO, 9).Value & """" & "," & _
                 Cells(GYO, 10).Value & "," & _
                 Cells(GYO, 11).Value & "," & _
                 Cells(GYO, 12).Value & "," & _
                 """" & Cells(GYO, 13).Value & """" & "," & _
                 """" & Cells(GYO, 14).Value & """" & "," & _
                 Replace(Cells(GYO, 15).Value, "/", "-") & "," & _
                 Cells(GYO, 16).Value & "," & _
                 Replace(Cells(GYO, 17).Value, "/", "-") & "," & _
                 Cells(GYO, 18).Value & "," & _
                 Replace(Cells(GYO, 19).Value, "/", "-") & "," & _
                 """" & Cells(GYO, 20).Value & """" & "," & _
                 """" & Cells(GYO, 21).Value & """"

        ' 改行をクリアして
        strREC = Replace(strREC, vbLf, "")
        strREC = Replace(strREC, vbCr, "")
        ' Redmine用に LFで改行
        strREC = strREC & vbLf

        If strREC <> "" Then
            ' レコード件数カウンタの加算
            lngREC = lngREC + 1
            ' レコードを出力。セミコロンでCRLFの改行抑止
            Print #intFF, strREC;
        End If

        '行を加算
        GYO = GYO + 1
    Loop
    
    ' 指定ファイルをCLOSE
    Close #intFF
    xlAPP.StatusBar = False

    MsgBox "ファイル出力が完了しました。" & vbCr & "レコード件数=" & lngREC & "件", vbInformation, cnsTITLE
End Sub
(3) wiki
  • wiki記法の修正が必要です
  • 手作業で移行してます。1日で終わらせる必要もなかったので、のんびりやってます。

データ移行 事後

TODOはこんなもんでした

  1. Eclipse宛先切り替え方法連絡

Project Tree Model

'Redmine project' tree model of this project has some characteristics. Like belows;

  1. 1st Layer: Root project
    • Defines Target versions
  2. 2nd Layer: Development project
    • Standard development project.
    • Bug, Change Tracking
    • Development team member's ToDo Tracking (ex. make a release build, Approve something, etc.)
    • Links to development SVN repository (Common Source Codes, Default Configurations, Specification Documents, etc.)
    • 3re Layer: Partner ISV project controls QA tickets about specifications.
  3. 2nd Layer: venders
    • Has vender projcets
    • 3rd Layer: Each verder project controls QA, Bug, RFC (core package improvement request) Tickets
  4. 2nd Layer: Group companies root
    • Has Each major version roots
    • 3rd Layer: Major version project has Release Tickets. A Release Ticket has links to each release ticket of this version's customer.
  5. 4th Layer: Each company project
    • Control system Integration team's QA, ToDo Tickets
    • Control service desk team's QA, Incident, RFC, Release, ToDo Tickets
    • Develops some custom programs if common programs can't reply to a company's needs.


Table of contents

  1. Introduction
  2. Ticket model (Redmine tracker model)
  3. Ticket workflow
    1. ToDo
    2. QA
    3. Bug
    4. Change
    5. Incident
    6. Relase
    7. RFC
  4. Project Tree Model

Ticket workflow - RFC

'RFC' Ticket's specification sheet is bvelow;

Status

    1. new *1
    2. assigned *2
    3. unapproved *3
    4. approved *4
    5. rejected *5
    6. construction *6
    7. resolved *7
    8. closed *8

Role

    1. Leader
    2. Developer
    3. Reporter

footnote

*1: 新規

*2: 担当中

*3: 承認前

*4: 承認済み

*5: 却下

*6: 対応中

*7: 解決

*8: 終了