• Active Directoryと apacheで 統合Windows認証

    ad_apache.png
    ウェブで事例を見かけて以来、やってみたいと考えていた。
    ↓このページを見て何度かトライしてみたんだけどずーっと上手くいってなかった。
    using mod_auth_kerb and Windows 2000/2003 as KDC

    けど、ついに自分ところの環境で動いたのでメモ。

    手順や設定はほぼ上のURLに書いてあるとおりなんだけど、自分のところでは
    KrbServiceName HTTP
    だとダメで
    KrbServiceName HTTP/ウェブサーバのFQDN
    にしたらあっさり通った。
    ネットで見かけた設定例だと「HTTP」か設定なしなので自分ところだけおかしいのか~。わからん。

    LogLevelをdebugにしてerror.logを見る。

    KrbServiceNameをHTTPに設定していると以下の通り「HTTP@ウェブサーバのFQDN」に対するcredentialを得ようとしているっぽい。
    [debug] src/mod_auth_kerb.c(1147): [client 192.*.*.*] Acquiring creds for HTTP@ウェブサーバのFQDN
    [error] [client 192.*.*.*] gss_acquire_cred() failed: An invalid name was supplied (Hostname cannot be canonicalized)
    keytabのプリンシパルはHTTP/www.example.cc@EXAMPLE.CCという感じなので@以降が補完されたとしても合致しないことになる。

    mod_auth_kerb.c(これは5.4のソース)のget_gss_credsを見ると「/」が含まれるかどうかで挙動が変わるっぽい。
       have_server_princ = conf->krb_service_name && strchr(conf->krb_service_name,'/') != NULL;
       if (have_server_princ)
          strncpy(buf, conf->krb_service_name, sizeof(buf));
       else if (conf->krb_service_name && strcmp(conf->krb_service_name,"Any") == 0) {
          *server_creds = GSS_C_NO_CREDENTIAL;
          return 0;
       }
       else
          snprintf(buf, sizeof(buf), "%s@%s",
               (conf->krb_service_name) ? conf->krb_service_name : SERVICE_NAME,
               ap_get_server_name(r));
    
    とにかく僕のところの環境ではKrbServiceNameにサービスプリンシパル名を記述することにした。
    副作用というかなんというか結果的にプリンシパル名中のFQDNとウェブサーバのFQDNが異なってても認証が通るのでVirtualHostを使っててもkeytabが同じでいいので手間は少ない?

    サーバ側の準備

    • ADサーバとドメイン構築
      • ADサーバからwebサーバのFQDNを引けるように。
    • ADサーバで
      • サービスマップ用のダミーアカウントを作成
      • ktpass.exeでサービスプリンシパルをダミーアカウントにマップしつつkeytabファイル作成
        ktpass.exe -princ HTTP/ウェブサーバのFQDN@EXAMPLE.CC 
        -crypto rc4-hmac-nt -ptype KRB5_NT_SRV_HST
        -mapuser ダミーアカウント@EXAMPLE.CC -pass パスワード -out 出力先ファイル名
      • 古いktpass.exeには問題があるそうなので、MSから最新版を入手して使った
        http://support.microsoft.com/kb/926027
    • webサーバで
      • /etc/krb5.conf設定
        [libdefaults]
         default_realm = EXAMPLE.CC
         dns_lookup_realm = false
         dns_lookup_kdc = false
         ticket_lifetime = 24h
         forwardable = yes

        [realms]
         EXAMPLE.CC = {
          kdc = ADサーバ
          default_domain = example.cc
         }

        [domain_realm]
         .example.cc = EXAMPLE.CC
         example.cc = EXAMPLE.CC
      • ADサーバ上で作ったkeytabファイルをwebサーバに持ってくる
      • apacheユーザから参照できるようにowner/groupを設定しchmodで400に
      • 認証領域設定。locationでもdirectoryでも。
            <Location /認証領域/>
                AuthType  Kerberos
                KrbAuthRealms EXAMPLE.CC
                KrbServiceName HTTP/ウェブサーバのFQDN(keytab作成したときと同じ名前)
                Krb5Keytab keytabファイルのpath
                KrbMethodNegotiate on
                KrbMethodK5Passwd off
                Require valid-user
      • reloadなり再起動なり

    クライアント側の準備

    • クライアントPCをドメインに参加させる
    • ドメインユーザでログオン
    • IEの場合
      • オプションから統合Windows認証を有効に。デフォルトは有効
      • 統合Windows認証の対象にしたいサイトのドメインを「イントラネット」扱いに設定
        • [ツール]→[オプション]→セキュリティタブ→「サイト」ボタン→「詳細設定」ボタン
        • ドメインを入力して→「追加」ボタン
        • httpsを必要とするかどうかは適宜
    • Firefoxの場合
      • about:configを開く
      • network.negotiate-auth.trusted-urisを編集、統合Windows認証の対象にしたいドメイン名を設定

    環境

    CentOS: 5.2
      mod_auth_kerb-5.1-3.el5
      httpd-2.2.3-11.el5_2.centos.4
    W2k3 R2 EE SP2
      SupportToolsの更新版
      IE7
    Windows XP
      IE6
      Fx3.0.5

    おまけ

    統合Windows認証を通過するとREMOTE_USERが「user1@EXAMPLE.CC」のようにrealm付きの値になる。
    mod_auth_kerbが5.4の場合、KrbLocalUserMappingをonにしておくとrealm部分がstripされて上記例なら「user1」になる。
  • redmineの wikiマクロで graphviz その3

    Wiki Graphviz macro プラグイン
    例によって無保証です。
    説明はその2の方に。

    今回はハマったことというか知ったこととか。
    以下、redmine-0.8.0RC1前提で。


    redmineのwikiマクロに関して

    • ・{{macro_list}}マクロがデフォルトで入っていて、使えるマクロの一覧を表示できる。知らんかった。。
      • マクロ名と登録時に「desc」で指定した内容が表示される
    • {{include(Foo)}}マクロがデフォルトで入っていて、別ページをincludeできる。知らんかった。。
    • wikiマクロの登録は、Redmine::WikiFormatting::Macros.registerにブロックを渡す。
      • descにはwiki記法が使えるが、今にして思えばtextile以外のフォーマッタを使っている場合にマズイか・・・。
      Redmine::WikiFormatting::Macros.register do
        desc <<'EOF'
    Render graph image from the wiki page which is specified by macro-args.

      !{{graphviz(Foo)}}
      !{{graphviz(option=value...,Foo)}}

    * options are:
    ** format={png|jpg}
    ** layout={dot|neato|fdp|twopi|circo}
    ** target={_blank|any}
    ** with_source
    EOF
        macro :graphviz do |wiki_content_obj, args|
    (略)
    • マクロ本体はmacroにシンボルとブロックを指定する
      • ブロックの引数はWikiContentモデルとマクロの引数に指定した文字列を「,」で分割したArray
        • {{マクロ(引数)}}
    • wiki中の{{マクロ}}の都度ブロックが呼び出される
      • ブロックが返した文字列がマクロ展開後のHTMLとして出力される。
        nilを返すと元のマクロ記述がそのまま表示される
      • プレビュー時、ブロックが呼び出されたときに「プレビュー中のテキスト」を得られない
        • graphviz_meマクロで編集/プレビューしながら図を確認できたら便利だよなぁと思ったら渡ってくるのは保存済みのWikiContentモデルだった。
        • 新しいwikiページをプレビューするとobjにはnilが渡ってくる
      • ブロックはActionView::Baseのインスタンスから呼び出される
        • ブロック内でself.to_sしたら"#<ActionView::Base:0xxxxxxxxx>"だった
        • なのでself.controllerからキャッシュメソッドを呼び出したり出来る
        • graphvizマクロの場合、マクロ展開時(Viewのコンテキスト)、画像表示時(コントローラのコンテキスト)のコードをできるだけ共有したかったので都合がよかった
    • ブロックから例外を飛ばすとwikiビュー内にエラー表示できる
      Error executing the マクロ名 macro (メッセージ)

    redmineプラグインに関して

    • プラグインROOTのinit.rbで登録すると利用可能になる
      Redmine::Plugin.register :wiki_graphviz_plugin do
    • プラグイン固有のコントローラのrouteはプラグインROOTのroutes.rbで追加定義できる
      connect 'wiki/:id/:page/graphviz', :controller => 'wiki_graphviz', :action => 'graphviz'

    プラグイン設定関係

    • 管理→プラグイン→(プラグインごとの)設定で表示されるプラグイン設定画面
    • Redmine::Plugin.register時に、settingsで:partialに指定した設定画面を表示できる。
      settings :default => {'cache_seconds' => '0'}, :partial => 'wiki_graphviz/settings'
    • テンプレートはvendor/plugins/プラグイン/app/views/に置く
      • 簡単で便利だけど、:partialの指定を他のプラグインと同じにしてしまうと別のプラグインのテンプレートが適用されてしまうことがある。
      • extra/sample_pluginをセットアップした状態で:partialに同じ値を設定しておいたらsample_pluginの設定ビューが出てきてかなり悩んだ。 
      • わざと存在しないテンプレート名を指定しておくとテンプレートの検索パスがログに出る。これを見る限り、プラグインの検索パスが連結された状態になっているようだ。
        Missing template wiki_graphviz/_settingsi.html.erb in view path 
        ・・・・/redmine-0.8.0_RC1/vendor/plugins/wiki_graphviz_plugin/app/views:
        ・・・・/redmine-0.8.0_RC1/vendor/plugins/sample_plugin/app/views:
        ・・・・/redmine-0.8.0_RC1/app/views 
      • stylesheet_link_tagみたいに:pluginを指定してなんとかしてくれんだろうか
    • プラグインの名前が長すぎると、設定値を保存できるが再表示した際に値が正しく表示されない(デフォルト値が表示される)
    mysql> desc settings;
    +------------+-------------+------+-----+---------+----------------+
    | Field      | Type        | Null | Key | Default | Extra          |
    +------------+-------------+------+-----+---------+----------------+
    | id         | int(11)     | NO   | PRI | NULL    | auto_increment |
    | name       | varchar(30) | NO   |     |         |                |
    | value      | text        | YES  |     | NULL    |                |
    | updated_on | datetime    | YES  |     | NULL    |                |
    +------------+-------------+------+-----+---------+----------------+
    • 以前は「redmine_wiki_graphviz_plugin」という名前にしていた。redmine内部で「plugin_」が前置されて35文字になり、切れているのが原因っぽいが深追いしてない。プラグイン名を短くした。
    mysql> select * from settings;
    (中略)
    | 24 | plugin_redmine_wiki_graphviz_p | --- !map:HashWithIndifferentAccess
    cache_seconds: "2300"
    | 25 | plugin_wiki_graphviz_plugin    | --- !map:HashWithIndifferentAccess
    cache_seconds: "3600"
    (後略)

    Railsに関して
    ※redmine-0.8.0RC1同梱のもの。2.1?

    キャッシュ関係
    • config/environments/環境.rbに設定することで有効になる
      config.action_controller.perform_caching             = true
      config.action_controller.cache_store = :mem_cache_store, "localhost"
    • cache_storeの挙動が微妙に違う。
      • デフォルトのActiveSupport::Cache::MemoryStoreはrubyオブジェクトを格納/取り出しできる。当然といえば当然。
      • ActiveSupport::Cache::FileStoreは文字列前提
      • ActiveSupport::Cache::MemCacheStoreは、(内部で使っているMemCacheの挙動で)値の格納/取り出し時にマーシャリングが行われるので結果的にrubyオブジェクトを(大体)格納できる。
        • :rawオプションでマーシャリングをナシにできる。
    • Catalyst::Plugin::CacheのイメージでいたのでFileStoreからHashが復元されず「おっかしいな~?」てことになった。結局Graphvizマクロプラグインではmemcachedだけ対応とした。

    • ・viewからHEADに何か差し込みたい場合はcontent_forが使える。これは便利な仕組みだな~。
      <% content_for :header_tags do %>
         <%= stylesheet_link_tag "wiki_graphviz.css",
             :plugin => "wiki_graphviz_plugin", :media => :all %>
      <% end %>
    • 画像を出力するときは:text&:content_type指定かつlayoutナシのrender。
      render :text => img, :layout => false, :content_type => "image/png"
    • しかし、charsetをつけられてしまう。。。
      ActionController::Baseのassign_default_content_type_and_charsetを見るにContent-Transfer-Encodingがbinaryに設定されていないとデフォルトのcharsetがついてしまうようだ・・。



  • redmineの wikiマクロで graphviz その2

    wikimacro2.png
    前回のつづき。

    クリッカブルマップを吐き出すところまでいけたので公開。
    Wiki Graphviz macro プラグイン
    例によって無保証です。

    主なfeature

    • wikiマクロ、{{graphviz}}と{{graphviz_me}}を追加
    • wikiページをdot形式で記述し、これらのマクロから呼び出すことでグラフ画像をレンダリング
    • ノードにURL属性を指定するとクリッカブルマップに

    {{graphviz}} マクロ

    {{graphviz(Foo)}}
    {{graphviz(option=value,Foo)}}
    {{graphviz(layout=neato,target=_blank,with_source,Foo)}}
      
    • 指定したwikiページをdotテキストとみなしてグラフ画像をレンダリング。IMGタグを差し込む
    • オプションは以下のとおり
      • format={png|jpg}
        • 画像形式。
        • 現在のところpngとjpegだけ
      • layout={dot|neato|fdp|twopi|circo}
        • レイアウトエンジン指定。
        • デフォルトはdot
      • target={_blank|any}
        • クリッカブルマップを生成する際のTARGET属性に指定する値
        • 別ウィンドウで開くなら_blank
      • with_source
        • 画像の直後に読みこんだdotの内容をPREで出力

    {{graphviz_me}} マクロ

    // {{graphviz_me}}
    // {{graphviz_me(option=value)}}
    // {{graphviz_me(layout=neato,target=_blank,with_source)}}
      
    • 別のwikiページを指定する代わりにこのマクロを含むwikiページをレンダリング対象とする。これ以外は{{graphviz}}マクロと同じ。
    • 必然的に、dotフォーマット上のコメントアウトが必要。コメントアウトしないとレンダラがエラー終了する

    dotの書式や指定できる値については、Graphvizチュートリアルがまとまっていて便利。


    必要なもの
    • Redmine 0.8.0 RC1 or later.
    • Graphvizとrubyバインディング。本家でrpmを配布している。  http://www.graphviz.org
          graphviz-2.20.3-1.el5
          graphviz-gd-2.20.3-1.el5
          graphviz-ruby-2.20.3-1.el5
    • memcached (optional)


    インストール
    • redmine公式サイトの説明にもあるように、プラグインのアーカイブを展開してvendor/plugins/に配置してredmineを再起動するだけ(僕のところはmongrel+mod_proxy_balancerなので)
    オプション
    • レンダリングした画像をキャッシュしておくことができます。キャッシュを用いる場合は、memcachedとcache_storeを設定します。
    • cache_storeの設定例
           e.g.) config/environments/production.rb
           config.action_controller.perform_caching = true
           config.action_controller.cache_store = :mem_cache_store, "localhost"
    • redmineを再起動
    • プラグインの設定ページ(管理→プラグイン→Wiki graphviz macro plugin)で、キャッシュ秒数を1以上に設定

    僕の環境は以下のとおり。

    CentOS 5.2
      ruby-1.8.5-5.el5_2.6
        mongrel-1.1.5
        mongrel_cluster-1.0.5
        redmine-0.8.0_RC1
      memcached-1.2.6-1.el5.rf
      MySQL-server-5.0.51a-tritonn.1.0.10
      graphviz-2.20.3-1.el5
      graphviz-gd-2.20.3-1.el5
      graphviz-ruby-2.20.3-1.el5

    既知の問題
    • wikiのプレビューで編集中の内容をレンダリングできない
      (wikiマクロに編集中の内容を受け取るI/Fがない。。。)
    とりあえず上記の環境では動くみたい。



  • redmineの wikiマクロで graphviz その1

    graphviz_macro.png
    redmineのwikiでgraphvizが使いたい、と思ったのだった。

    どんだけgraphviz好きなんだって感じだけど、まぁ好きだ。

    実際は、別途webdot的なサービスを作って画像挿入のtextile記法、ってやり方で利用してはいたんだけどredmineプラグイン作成の習作も兼ねてやってみた。

    wikiにdotを記述して、別のwikiページからgraphvizマクロで呼び出すとIMGに置き換わる、という流れ。

    Wiki Graphviz macro プラグイン
    例によって無保証です。
    説明はその2の方に。

    環境は以下のとおり
    CentOS 5.2
      MySQL-server-5.0.51a-tritonn.1.0.10
      ruby-1.8.5-5.el5_2.6
        mongrel-1.1.5
        redmine-0.8.0_RC1


    WikiControllerから地味に追いかけていったら元々マクロを拡張するI/Fを持っていて、lib/redmine/wiki_formatting/macros.rbに説明があった。
            #   Redmine::WikiFormatting::Macros.register do
            #     desc "This is my macro"
            #     macro :my_macro do |obj, args|
            #       "My macro output"
            #     end
            #   end
    
    ということらしい。

    次はどこでマクロ登録を行うか。
    redmineのプラグイン機構に乗っかってプラグインの初期化時にやったらよさそう、ということでscript/generateを使ってひな形を作成。

    % script/generate redmine_plugin wiki_graphviz_plugin
          create  vendor/plugins/redmine_wiki_graphviz_plugin/app/controllers
          create  vendor/plugins/redmine_wiki_graphviz_plugin/app/helpers
          create  vendor/plugins/redmine_wiki_graphviz_plugin/app/models
          create  vendor/plugins/redmine_wiki_graphviz_plugin/app/views
          create  vendor/plugins/redmine_wiki_graphviz_plugin/db/migrate
          create  vendor/plugins/redmine_wiki_graphviz_plugin/lib/tasks
          create  vendor/plugins/redmine_wiki_graphviz_plugin/assets/images
          create  vendor/plugins/redmine_wiki_graphviz_plugin/assets/javascripts
          create  vendor/plugins/redmine_wiki_graphviz_plugin/assets/stylesheets
          create  vendor/plugins/redmine_wiki_graphviz_plugin/lang
          create  vendor/plugins/redmine_wiki_graphviz_plugin/test
          create  vendor/plugins/redmine_wiki_graphviz_plugin/README.rdoc
          create  vendor/plugins/redmine_wiki_graphviz_plugin/init.rb
          create  vendor/plugins/redmine_wiki_graphviz_plugin/lang/en.yml
          create  vendor/plugins/redmine_wiki_graphviz_plugin/test/test_helper.rb
    extraのsample_pluginを真似して上記プラグイン名にしたのだけど、これが元で後で痛い目に。「redmine_」が前置された結果、プラグインの名前が30文字を超えてしまいプラグイン設定の更新・参照に問題が発生。
    ※settingsテーブルのname属性がvarchar(30)なことが原因っぽい

    なので、手作業で「wiki_graphviz_plugin」に変更した。
    ※今にしてみれば_pluginを削ったらよかったのか。。。。

    拡張マクロの登録は、プラグインのinit.rbでプラグイン登録と同時にやってみた。これが正しいかはわからない。
    require 'redmine'

    RAILS_DEFAULT_LOGGER.info 'Starting wiki_graphviz_plugin for Redmine'

    Redmine::Plugin.register :wiki_graphviz_plugin do
    name 'Graphviz Wiki-macro Plugin'
    author 'tckz'
    description 'Wiki macro to render the graph using graphviz'
    version '0.0.1'
    settings :default => {'cache_seconds' => '0'}, :partial => 'wiki_graphviz/settings'

    Redmine::WikiFormatting::Macros.register do

    desc "Render the wiki page into graph image using graphviz.\n\n" +
    " !{{graphviz(Foo)}}\n" +
    " {{graphviz(format={png|jpg},Foo)}}\n" +
    " {{graphviz(layout={dot|neato|fdp|twopi|circo},Foo)}}\n"
    macro :graphviz do |obj, args|

    end
    end
    end

    こんな感じで登録しておくと、wikiページ(view)のレンダリング中に呼び出される。マクロ展開後のHTMLを返せばOK。

    dotの構文に誤りがあったときはwikiマクロのエラーとして表示する形にしたいからIMG要素出力時点で一度画像をレンダリングする方向で。dot解釈時点で一旦レンダリングしたものをrailsのキャッシュに置いておいて実際の出力時はキャッシュから返す(ない場合は改めて生成)という感じ。

    その2につづく
  • JUDEで FP

    失敗のないファンクションポイント法
    受託開発の見積りをすることがある。

    このフェーズにおいてもJUDEを利用しています。
    以前はモデリングはともかく数字の部分が「KKD(経験・勘・度胸)」だったのだけど、ここ二年ぐらいはファンクションポイントによる見積りにチャレンジしているのです。
    ※機能規模と関連の薄い部分(導入とか利用者トレーニングとかバッファ)は相変わらずKKDだけど。

    • ヒアリングしたメモをマインドマップにざらーっと書き出しつつ、思いついたことをちょいちょい書き足す
    • マインドマップを見返しながらアクターとユースケースを並べる
    • ざーっとエンティティを見出す
    • CRUDを埋める
    • FP計数
    という感じで。

    かなり詳細にシステム像をイメージしないと数字が出せないのが難点といえば難点だけど、どんなものを作るかわからないのに見積り数字が出るってのも変といえば変。
    それに計数を重ね記録することで、(組織/チームとしての)生産性が見えることがわかったのは収穫だったと思う。

    で、

    せっかくJUDEでモデリングしているのだから、これを活かしてFP計数が出来ればなお効率もいいだろう、という話し。
    すでにやっておられる方がいるので今更感はあったのだけど、これも理解を深めるため&自分都合の使い易さのためということで。

    judeユーティリティ

    ■実行環境
     OS: CentOS 5.2 i386
       libxml2: 2.6.26-2.1.2.6
       ruby: 1.8.5-5.el5_2.3
         rubygems: 1.2.0
         libxml-ruby: 0.8.3 (gem)
       JRE: Sun Java 1.6.0_07
         jruby: 1.1.4
         JUDE-Pro: 5.4

    ※注意:プログラムの実行結果について作者はなんら責任を持ちませんので悪しからず。

    このFP計数ユーティリティにおける前提条件は以下のとおり。
    • データファンクション(以下DF):
      • JUDEモデルでいうと以下のいずれかで、属性が1つ以上あるものをDFとみなす。
         <<entity>>なclass
         ERエンティティ
    • DFのファイルタイプ(ILF/EIF):
      • CRUD図で当該エンティティに対する操作の有無で判断、または手動付与
         Rのみのエンティティ→EIF扱い
         CUDのいずれかが設定されているエンティティ→ILF扱い
    • DFのDET:
      • 非PKな属性の数をDETとみなす
      • JUDE APIを jrubyから使う その1 」で書いたようにIdentifierを使ったモデリングをするようにしているので、主キーにはユーザ識別可能なデータは出てこない、とみなしています
    • DFのRET:
      • 考えられるグループを@retアノテーションで列挙する。列挙された@retアノテーションの数をRETとする。
      • ここでのアノテーションとはjavaのアレではなく、JUDEにタグ付き値がなかったころに独自データを付与するため作ったオレオレ表記。
        モデルの定義中の「@アノテーション名(空白)値」という記述部分を抜き出してデータとします。
      • とあるエンティティが「xxx種別」の値で意味合いを制御するようなモデリングの場合に、
         @ret xxx種別が講師の場合
         @ret xxx種別が講師以外の場合
        のようにエンティティの定義に記述することでRET=2と計数します
    • トランザクショナルファンクション(以下TF)は、JUDEモデルでいうとユースケース1つに対応するものとします。
    • TFのファイルタイプ(EI/EO/EQ):
      • TFのCRUD操作から判断させるか手動で付与します
        • RのみのTF→EO
          CUDあり→EI
        • ユースケースに対して@tfアノテーションで明示指定
           @tf eo
           @tf ei
           @tf eq
      • 結果的にCRUDからはEQが出てこないのだけども、全く加工のない操作って少ないのではないかと考えたから
    • TFのFTR:
      • 当該ユースケースのCRUDで操作対象となっているエンティティの個数をFTRとします
    • TFのDET:
      • ここはまだ方式を確立しかねている
      • 現状は、当該TF(ユースケース)の直下に「FP-」で始まる名前のシーケンス図を書き、アクターが発するメッセージから計数することにしています
        例:「FP-社員情報を登録する」みたいな感じで。
      • DET=メッセージ(=トリガ)+操作の引数の個数+返り値の個数
        • 「操作」に対して返り値は1つしか指定できないので、返り値にclassを指定した場合はその属性の数を返り値の個数とします
        • あるいは、返り値ではなく「操作」の「out」パラメータとして記述します

    FP計数周辺に絞った手順

    1. モデリング
    • ユースケースをモデリング
      • TFのDET計数用シーケンス図作成
    • ERモデリング(クラス図でもよい)
    • CRUD表作成してユースケースとエンティティの操作を結びつける
    2. 計数元ネタファイル作成
    • judeファイルからAPIを使ってFP計数に必要な情報を抽出→中間XMLファイル
      ※linuxの操作例
      % env CLASSPATH=./jude-pro.jar jruby ./jude_export.rb -o 出力中間.xml 入力.jude
      

    • 中間XMLファイルからFP計数→TSVファイルに出力
      ※linuxの操作例
      % ./calc_fp.rb -e cp932 -o 出力.txt 入力中間.xml
      

    • TSVファイルを雛形xlsに貼り付けて集計
      • TSVファイルをテキストエディタで開いてコピー&ペースト
      • アーカイブにFP-hinagata.xlsというxlsブックが入っています。TSV全体をコピペで[ファンクション]シートに貼り付けます
      • もし既存の表をはみ出たら適宜書式をコピーしておきます
    3. FP計数
    • 一般システム特性記入
      • [一般システム特性]シートに数字を入れます
      • この辺が参考になります
    • 雛形xlsのピボットテーブル更新
      • [業務単位FP集計]シート
      • [FP概算法]シート
      • [FP試算法]シート
      • FP概算法、FP試算法についてはこの辺を参考にしました。
      • 個人的な感覚では試算法だと数字が離れるなーという印象。rapidに見積もる必要がある、あるいは画面項目を想定するほど情報が揃っていないときは概算法のほうがいいなという感触。


    ファンクションポイント法自体については「失敗のないファンクションポイント法 」という本を参考にしています。
    この本は項目説明が網羅されているだけでなく例示が勉強になります。300ページちょいの本ですが、約200ページを「計測実習」に割いており非常に具体的で参考になります。