Virtual PCでWindows Embedded Compact 7を動かしてみる

MSDNサブスクライバからWindows Embedded Compact 7が落とせるようになっていたことには気がついていたので(・∀・)
自分も、Platform BuilderでビルドしたWindows Embedded Compact 7のイメージをVirtual PCを使って動かしてみたのでした。

自分もやってみたいという人は、下記のURLを参考にどぞ(・ω・)つ

概要

詳細はリンク先を見ればわかるので、やることの概要だけ書いておくとこんな感じです。

っという流れ。


後は、自分がはまったポイントについても書いておきます。

DHCPサーバを忘れない

仮想マシンDHCPIPアドレスを取得して動作するので、DHCPサーバを忘れないように。
自分の場合、DHCPサーバはいたんだけど、リソースが全て払い出し済みだったというオチなんだけど…(´д`;)

TFTPでのイメージダウンロードに失敗する

仮想マシンDHCPIPアドレスを取得し、TFTPでイメージを取得しにいった後に次のようなメッセージが表示されてしまい(・ω・;)

ERROR: BootTransportPb: TFTP timeout occured!

ちょっと調べたら、UDPチェックサムを無効にしたら良いんじゃよ、っという記述があったのでやってみたら解消しました。
↓みたいな、ネットワークドライバの設定の話ね。


さて、個人的にはWP7よりも、WEC7ベースの業務用ハンディが気になっていたりもするわけですが(・∀・;)
ただまあ、昨今のAndroid端末なんかも見ていると、アプリケーションプラットフォーム的な意味でのWECは微妙かな〜と思わなくもなかったり(・ω・;)
カーネル的な意味でのWECは好きだし、本業の組込屋さんにとってはそれが標準でしょうけど、アプリケーションプラットフォームとして考えた場合、やっぱりちょっと「素」すぎるんですよね。
各種サービスを抽象化してモダンなオブジェクトモデルを用意したり、用途毎のプロファイルフレームワークみたいなものが強化されないと、上位層よりのアプリを作る人としては物足りないかな(・ω・)?、とか。


量販店のバックヤードとか物流の現場で使っているようなハンディーターミナルについては、現状Windows CE端末意外にHW的にも適合するものが無いし、しばらくは置き換わらないでしょうが。
でも、検針端末とかセールス端末みたいなものについては、Android端末もありかな〜という気にはなっていて。


UI的な表現力や作りやすさは十分にあるし、データアクセスや通信についても事足りているし。
一方で、デバイス関連、ラインプリンタ制御とかバーコードリーダーのHW的特性(単にカメラで読めれば良いと言うことでは無くて、接写できるタイプかどうかとか)みたいな所は不十分なので、バックヤードにはまだ無いと思っていますけど。
あと、アプリケーションアーキテクチャ的な部分について言えば、画面遷移、DI、バインディング、ヴァリデーションとかもイメージはできつつあるので(`・ω・´)
そういったインフラストラクチャ層を用意して、APTを使った自動生成なんかの仕組みも用意すれば、かなり良い感じでAndroidでも業務アプリが作れるよね〜、つって(・∀・)


〜とか、3月は主にAndroidで遊んでいた*1人は思うのでした(・ω・)

*1:といっても、半分以上NDKを弄っていたんだけど(・ω・)

Smart.Windows.Navigation改めSmart.Navigation & Smart.Navigation.Windowsに分離 0.5リリース

変更したのは去年の話なんだけど、CodePlexにあげていなかったので、今更リリース通知(・∀・;)
画面遷移フレームワーク、Smart.Navigation 0.5ということで。
http://usaxusa.codeplex.com/releases/view/59805

修正内容

元々こいつはWindows Forms以外にも対応できるように作っていたつもりなんだけど、実装としてはWindows Forms用の処理しか用意していなくて、アセンブリ
System.Windows.Formsを参照するようになっていて(・ω・;)
ちょっと弄る用途があったので、その際に遷移機能のコアとWindows Forms依存部分を分離して、それぞれSmart.Navigation、Smart.Navigation.Windows.Formsとしたのでした。


ついでに、Windows Formsに依存していない証拠として、WPF用のSmart.Navigation.Windows.Controlsも追加。
動きとしては、Windows Forms版がSystem.Windows.Forms.ControlのControlsに対して画面Controlを追加するのに対して、WPF版はSystem.Windows.Controls.ContentControlのControlを置き換える動作。
WPF版はとりあえず作った物なので、サンプルも用意していなければ、MVVMとこれをどう連携させるかとかまったく考えていませんが(・∀・;)


なお、使い方は以前の版からまったく変わっていないので、サンプルを見るか、この日記から「Smart.Windows.Mvc」で検索した内容を参照してくださいな(・∀・)
Smart.Windows.Mvcの検索結果

SA取ったど〜(´・ω・`)

はい、SAも取ったので、恒例の「資格を取ったからこそdisりますよ」シリーズです(・∀・;)


さて、一般的には、「システムアーキテクト」と言う言葉は2通りくらいの意味で使われていると思うわけですが( ・ω・)


一つ目のケースは、こういう感じのやつで。

  • 戦略的〜ビジネスの観点から〜みたいな話と、テクノロジーをリンクして語る
  • アーキテクトと言うか、CIO補佐というかCTOと言うか
  • スーパーマンで、そんな人は日本に何人もいないよ、みたいな人達(´д`;)

二つ目のケースは、こういうの感じのもので。

  • フレームワークの選定をしたり(・ω・)
  • システム構成のレイヤと機能による水平/垂直の分割をしたり(・ω・)
  • トランザクション戦略を決定したり(・ω・)
  • 一通りのサンプルを作って展開したり(・ω・)
  • 非機能要件を考慮して処理を非同期化することを決めたりとかも(・ω・)
  • 足りないライブラリは自作したり(・ω・)
  • ROIやシステムのライフサイクルメンバーのスキルレベルなんかを考慮して方針を決定したり(・ω・)
  • あるいは自称アーキテクトだったり(´д`;)
  • 格好つけなければチーフプログラマーで良いじゃん( ゚д゚)
  • 自分は使い分けるために「狭義の意味でのアーキテクト」とかよぶもの

…っとまあ、アーキテクトという言葉は文脈により異なる意味や、都合良く使われたりするものだと感じているわけですが(・∀・;)


っで、情報処理技術者試験で言うところのシステムアーキテクトっていう奴は、上の二つともまた違うものを想定しているかな〜っという感じで(゚Д゚;)
少なくとも、海外の書籍に出てくるシステムアーキテクト(こっちは狭義の意味でのアーキテクトの方が近いかな?)から想像するものとは別の、日本的なるもの情報処理技術者試験のSAだと思うわけで(´・ω・`)
しかも、その想定する人物像というのが、ちょっとどうなんだろう…というのが自分の考えなわけですが。


どこが気に入らないかと言えば、「アーキテクト」を入れている割には非機能要件に関するアーキテクチャ設計能力があまり求められていないところと言うか(´・ω・`)
どちらかというと、非機能要件的なアーキテクチャはあまり考えなくて良い世界での、業務要件的な事が主体な感じで。*1


特に酷いと思ったのが、情処で言うSAの人物像として、プログラミングはやらないで上流工程(笑)をやる人、みたいな定義しているところとかですね(・∀・#)
想定する人物像には、SAはプログラム開発工程を担当しないとかも書いてあるんですよ。
氏ねば、良いのにネ(・∀・)
そして、専門知識についてはNEやDBに相談する、みたいな事も書いてあって、おまえは何をやるの( ゚д゚)?、っとか。
だいたい「アーキテクト」がテクノロジースペシャリスト系に分類されていないってどういうこと(゚Д゚ )?、っとか。


まあ、何をやるか決めるところまでやって、どうやるかには一切関与しないというポジションも無くはないですが、それをアーキテクトとか言うなよ、って。
アーキテクトと名乗るからには、手を汚して、自分で正しさを判断してなんぼでしょ、つって。
あれですか?、「プログラマー」と「PG」、海外で言うところの「Systems Engineer」と「SE」が異なるものを意味するように、洋書に書いてるような「システムアーキテクト」と「SA」も違うものを指す、っという理解でOKですか(´д`;)?


まあ、情処で言うところのSAみたいな人が不要と言うわけではないけど、この内容ならむしろ「上流SE(笑)」「Advanced SE :p」略してASとかで良いじゃんなんて思ってみたり(・∀・)
っというか、昔のAEから変える必要があったの( ゚д゚)?、っとか。


っで、中途半端に格好つけた名称を使うことにより、非機能要件とか本当の意味でのアーキテクチャとかが、かえって軽視されないかが一番の心配事項なわけですが(´・ω・`)
今のSAの内容では、アーキテクチャ設計の重要性が伝わらないよね〜、と思ったりして。


少し真面目な話をすれば、PM、テクノロジースペシャリスト、ドメインエキスパートによる三権分立というやり方は鉄板なので、現行のSAは分割して、非機能要件的な面を主体とした新SAと、もっと業務系の色を強くした「ドメインエキスパート」略してDEみたいなものにするのが良いんじゃないかと思うわけですが(・ω・)


今の内容の資格を持って「私はアーキテクトでござ〜い、設計は任せてくだし」とか言われても、そんなうぜーバカはまともに相手をしなくて良いかと思っちゃうしね(´・ω・`)
だいたいですよ、2〜3年くらい前までならまだしも、クラウドとかサービスシフトとかマルチパラダイム設計と言っている今時の開発では、開発メンバー全員に狭義のアーキテクト程度の意志決定能力は求められるし、アーキテクトを自称したい人にはもう一段上の設計能力が求められる時代だと思うわけでして(・∀・;)
ピントのずれたSAとか、業界の不健全な発展に貢献するものだと思ったり、ぬるい事言ってる自称アーキテクトは、おウンコ召し上がれでございますわ、なんつって(・∀・)

アーキテクトという言葉はどうでも良いけど、アーキテクチャを軽視しないためによんでおくべき本

…とかいうのをやろうとも思ったんだけど、良く考えたらプログラマ向け10冊(ただし本家、カレー方面のみ)とそう変わらない様な気もしてきた(・ω・;)ので、アーキテクトっぽい読み物として、読みやすく楽しめる本をいくつか紹介してみたいと思います(・∀・)


まずは読んで笑えて楽しめることろから。

間違いだらけのソフトウェア・アーキテクチャ―非機能要件の開発と評価 (Software Design plus)

間違いだらけのソフトウェア・アーキテクチャ―非機能要件の開発と評価 (Software Design plus)

これは読んでて爆笑しましたよ(・∀・)
笑えるだけでなく、ちゃんと参考になることも書いてあるし。


っで、今まで何回か紹介していますが、次はこれ。

Release It! 本番用ソフトウェア製品の設計とデプロイのために

Release It! 本番用ソフトウェア製品の設計とデプロイのために

併せて読みたいというとこではこちらもどうぞ。

Manage It! 現場開発者のための達人式プロジェクトマネジメント

Manage It! 現場開発者のための達人式プロジェクトマネジメント

っで、アーキテクトとつく書籍と言うことで、この辺も。

ソフトウェアアーキテクトが知るべき97のこと

ソフトウェアアーキテクトが知るべき97のこと

キノコ亭シメジについてはまた近いうちに(・ω・)


っで、アーキテクチャというか、若干Web屋よりの基礎教養的な内容になりますが、技評のこのシリーズもどうぞ(・∀・)

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

[24時間365日] サーバ/インフラを支える技術 ?スケーラビリティ、ハイパフォーマンス、省力運用 (WEB+DB PRESS plusシリーズ)

[24時間365日] サーバ/インフラを支える技術 ?スケーラビリティ、ハイパフォーマンス、省力運用 (WEB+DB PRESS plusシリーズ)

Googleを支える技術 ?巨大システムの内側の世界 (WEB+DB PRESSプラスシリーズ)

Googleを支える技術 ?巨大システムの内側の世界 (WEB+DB PRESSプラスシリーズ)

あとこれも。

4Gbpsを超えるWebサービス構築術

4Gbpsを超えるWebサービス構築術

コンシューマーWeb屋だけでなくイントラSI屋であっても、この辺は一通り読んでおくべきかなっと(・ω・)


っで、アーキテクトついでで思い出したけど、〜のやってはいけない、みたいなムックがありましたが。
アレは一部微妙なところがあるというか、アーキテクトだけでなく誰でも知っておくべき事が書いてあったりだとかで、紹介はしませんが。
つーかね、アーキテクトって言うからには守についてだけ語っていても駄目で、破離の検証、実践を常に行っていないとね(`・ω・´)


アーキテクトの能力なんて、理論と実践の反復でしか身につかないと思うわけで(・ω・)

  • 戦略的に理論や知識を蓄積する、プロジェクトを通してインバスケットで意志決定を繰り返す
  • 数字(例えば原価)としてその成果を確認する
  • 理論と実践の反復を行い、成果を確認することで、やっと基本となる型がわかってくる
  • でも、そこはまだアーキテクトとしての出発点にすぎなくて(´д`;)
  • 知識の蓄積、実践での試行錯誤、その結果のフィードバック
  • いくつものプロジェクトでそれを繰り返すことで、破の段階から離の段階へと移行し、やっと自信を持って、アーキテクチャについて語れるようになるヽ(・∀・)ノ

…っていう感じだと思うのよね(・ω・)?


実践と試行錯誤無き知識は「頭でっかち」って言うし、仮説とフィードバックの無い試行錯誤は「無駄な努力」って言うんですよ、つって(・∀・;)


っで、書籍の話に戻りますが、今回は読み物的なところを紹介しているので、SEのIT Architects' Archiveあたりは除外。
あと、PoEAAとかそっちも除外。
この辺は読む価値があるものなので、真摯にアーキテクトを目指す方は是非読んでくださいな(・∀・)


あと、書籍じゃないけど、アーキテクトを名乗るならフレームワークのソースは読め、つって(`・ω・´)
出来ればいろんな言語のものを、比較したりもしながら。



…っで、情処のSAをdisったり、アーキテクトについてちょっとだけ語ってみたりしたわけですが(・ω・)
まあ、なんだかんだ言いつつ、報奨金はありがたく頂くんですけどね〜(・∀・)

*1:これは、プログラムなんて制御構造がかければ十分だ、SQLが出来ればシステムは作れる、…的な、典型的なSI屋の発想に繋がっていく気もするわけですが、それをアーキテクトと言われてもねぇ〜(´д`)

Mono 2.8上でSmart.Web.Mobileを使ってみる

最近、ちまちまとMonoを試していたのでメモ。


Monoも、Linux上でyumやapt-get一発で最新版がインストールされるようになると、もう少し弄ってみる気になるんですが(・ω・)
手動インストールも一つや二つなら良いんですが、依存関係が多くなってくると面倒で(´・ω・`)
…などと思いつつWebをブラブラしていたら、インストール用のスクリプト*1を作っている人が居たので、MonoでASP.NET 4.0する環境を自分も作ってみました。
元情報はこちら。
Setting up Mono 2.8 with Asp.Net 4.0 and MVC2 on Ubuntu with MySql Membership
スクリプトUbuntu用とFedora用があるみたいですが、今回はUbuntuで試してみました。*2

Ubuntu

まずはUbuntuの用意から(・ω・)
自分はVMwareを使ってVM上に環境を構築。
Ubuntu Server 10.04をダウンロードしてきてインストール。
以下、Ubuntu Serverのインストールについてざっくりと(・ω・)

  • VMUbuntu Linux (64-bit)で作成
  • インストール開始、Languageは日本語
  • キーボードは適当なのを選択、なんとなくMicrosoft Natural Wireless Ergonomic Keyboard 7000とかで、レイアウトはJapanで
  • ネットワークはDHCPで入れて後で固定に変更
  • パーティションとかはデフォルトでディスクに書き込み
  • ユーザー名、パスワードを入れて、ホームディレクトリの暗号化はしない
  • プロキシを入力、自動アップデートは無しで、ソフトウエアの選択ではOpenSSH serverのみを選択しておく
  • ブートローダーはデフォルト

これでインストールは完了(・ω・)
ついで初期設定。

とりあえずIPアドレスを固定に変更。

sudo vi /etc/network/interfaces
auto eth0
#iface eth0 inet dhcp
iface eth0 inet static
address x.x.x.x
netmask x.x.x.x
gateway x.x.x.x
sudo /etc/init.d/networking restart

ついでソフトウエアを最新版に更新。

sudo apt-get update
sudo apt-get upgrade

VMware Toolsのインストールについては省略。
これでOSの準備はOK、次はMonoのインスコ(・ω・)

Mono

GitHubからインストールスクリプトを取得して実行。

wget --no-check-certificate https://github.com/nathanb/iws-snippets/raw/master/mono-install-scripts/ubuntu/install_mono-2.8.sh
chmod +x install_mono-2.8.sh
./install_mono-2.8.sh

コンパイルに時間がかかるのでしばらくおやつタイム(・∀・)
コンパイルが終わったら、/etc/environmentにパスを追加。

sudo vi /etc/environment
PATH="/opt/mono-2.8/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"

GUI周りをインストールするとMono 2.4が入るようですが、自分で入れた2.8を優先するように設定。
っで、設定を反映させた後で実行結果の確認。

machi@vm-mono-ubuntu:/srv/www$ mono -V
Mono JIT compiler version 2.8 (tarball 2010121日 水曜日 18:19:26 JST)
Copyright (C) 2002-2010 Novell, Inc and Contributors. www.mono-project.com
        TLS:           __thread
        SIGSEGV:       altstack
        Notifications: epoll
        Architecture:  amd64
        Disabled:      none
        Misc:          debugger softdebug
        LLVM:          supported, not enabled.
        GC:            Included Boehm (with typed GC and Parallel Mark)

MonoのインストールまではこれでOK。
後はApacheでmod_monoを有効にするための設定を。

cd /etc/apache2
sudo mv mod_mono.conf mods-avail*
sudo ln -s /etc/apache2/mods-available/mod_mono.conf /etc/apache2/mods-enabled/mono.conf
sudo service apache2 restart

Ubuntuだと設定ファイルが細かく管理されてんのね(・ω・)

Webアプリ

次にアプリケーションの設定を。
今回はSmart.Web.Mobileのサンプルと、それとは別に新規作成したWebアプリケーションの2つを、別アプリケーションプールに配置するような設定にしてみます(・ω・)
Smart.Web.Mobileのサンプルと、新規に作成したWebアプリケーションをそれぞれVisual Studio 2010でビルドしておきます。


っで、サーバ上の設定については、/srv/wwwディレクトリ下を各アプリ用の仮想ディレクトリとして使用する事にします。
まずはディレクトリを用意して。

sudo mkdir /srv/www

次に、この下にビルドしたアプリケーションを配置します。
今回はSmart.Web.Mobileのサンプルをmobileディレクトリに、新規に作成したWebアプリケーションをsampleディレクトリに配置します。
っで、配置が終わったら権限をば設定。

sudo chown root:www-data /srv/www -R
sudo chmod 775 /srv/www -R

こんな状態になっていればよかとですたい(・ω・)

machi@vm-mono-ubuntu:/srv/www$ ls -al
合計 24
drwxr-xr-x  6 root www-data 4096 2010-12-02 18:57 .
drwxr-xr-x  4 root root     4096 2010-12-02 18:24 ..
drwxr-xr-x 16 root www-data 4096 2010-12-02 17:03 mobile
drwxr-xr-x 11 root www-data 4096 2010-12-02 18:56 sample

machi@vm-mono-ubuntu:/srv/www$ ls -al mobile/
合計 92
drwxr-xr-x 16 root www-data 4096 2010-12-02 14:03 .
drwxr-xr-x  6 root www-data 4096 2010-12-02 13:57 ..
drwxr-xr-x  2 root www-data 4096 2010-12-02 18:49 App_Browsers
drwxr-xr-x  3 root www-data 4096 2010-12-02 18:49 App_Data
drwxr-xr-x  2 root www-data 4096 2010-12-02 18:49 Content
...

そして仮想ディレクトリの設定を行います。

sudo vi /etc/apache2/sites-available/mono.conf

内容についてはこんな感じで。

Alias /mobile/ "/srv/www/mobile"
Alias /sample/ "/srv/www/sample"
#Alias /sample2/ "/srv/www/sample2"

AddMonoApplications mobile "/mobile:/srv/www/mobile"
AddMonoApplications sample "/sample:/srv/www/sample"
AddMonoApplications sample "/sample:/srv/www/sample2"

MonoServerPath mobile "/opt/mono-2.8/bin/mod-mono-server4"
#MonoDebug mobile true
MonoSetEnv mobile MONO_IOMAP=all

MonoServerPath sample "/opt/mono-2.8/bin/mod-mono-server4"
#MonoDebug sample true
MonoSetEnv sample MONO_IOMAP=all

<Location "/mobile">
    MonoSetServerAlias mobile
    SetHandler mono
</Location>

<Location "/sample">
    MonoSetServerAlias sample
    SetHandler mono
</Location>

#<Location "/sample2">
#    MonoSetServerAlias sample
#    SetHandler mono
#</Location>

mobileとsampleの2つのアプリケーションプールを作って、Smart.Web.Mobileのサンプルと新規作成したサンプルをそれぞれに設定する感じ(・ω・)
っで、sites-enabledの方にもリンクを張って再起動。

sudo ln -s /etc/apache2/sites-available/mono.conf /etc/apache2/sites-enabled/000-mono.conf
sudo service apache2 restart

これで、http://server/mobile/にアクセスするとSmart.Web.Mobileのサンプルが、http://server/sample/にアクセスすると新規作成したサンプルにアクセスできることが確認できます(・∀・)
プロセスもこんな感じでMonoが動いている事を確認できます。

machi@vm-mono-ubuntu:~$ ps -aux | grep mono
www-data  1242  0.5  5.3 197356 55008 ?        Ssl  19:39   0:02 /opt/mono-2.8/bin/mono **debug /opt/mono-2.8/lib/mono/4.0/mod-mono-server4.exe **filename /tmp/mod_mono_server_mobile **applications /mobile:/srv/www/mobile **nonstop
www-data  1244  0.3  3.2 173100 33268 ?        Ssl  19:39   0:01 /opt/mono-2.8/bin/mono **debug /opt/mono-2.8/lib/mono/4.0/mod-mono-server4.exe **filename /tmp/mod_mono_server_sample **applications /sample:/srv/www/sample **nonstop

動作確認

ssbでの表示結果ですが、レスポンスヘッダの所を参照(・∀・)


まとめ

っで、これでLinuxサーバ上でMonoを使い、Smart.Web.Mobileを使ってガラケー向けサイトも作れるようになった(?)わけですが…。
ぶっちゃけ、公開サービスで.NETしたかったら、実際にはクラウドなりなんなり使えば良いと思うので、こんなことしないと思うんだけどね(・∀・;)
むしろ、イントラとかでLinux上に載らなければいけないケースで、でもWebアプリは.NETで作りたいな〜なんて時にはありかもしれない(`・ω・´)
色々動かしてみた感じ、思った以上に問題なく動く感じだし(・∀・)


今回はMonoDevelopは入れていないので、Visual Studio 2010上でビルドしたものをそのままサーバにコピーして実行しましたが。
出来れば、サーバ上で自動ビルド、自動テスト、自動デプロイまでの環境を構築したいところですね(・∀・)

*1:やっていることはダウンロード、makeのバッチ実行だけど。

*2:普段はCentOSを使っている自分なのでFedoraの方が填らなかったのかも(´д`;)

Silverlightでカスタムページングをしたい時

また日記を放置していたので、月一くらいでは小ネタも書いておこうかと(・∀・;)
元ネタはこちらですが、ちょっと使ったのでSilverlightでのカスタムページングについて。
http://weblogs.asp.net/manishdalal/archive/2009/10/01/silverlight-3-custom-sorting-with-paging-support.aspx


SilverlightでDataGrid、DataPagerを使ってデータ管理アプリケーションを作るときの話ですが(・ω・)
Silverlightで作ったクライアントにデータを提供するサービス側も.NETで作って、WCF RIA ServicesでLinqToEntitiesDomainServiceなんかを使えば、ページング処理なんかも楽ちんぽんと作れて、ちゃんとSkip() & Take()した必要なデータだけの取得なんかも出来ちゃうわけですが。
でも、サービス側がJava製だったり既存のRESTなサービスを使いたいときとか、パラメータを自分で組み立ててデータ取得の通信を行いたいときにはどうするか(・ω・)?
もちろん、ページに必要なデータのみをオンデマンドで取得する方法で。*1


っで、そこで登場するのが、ICollectionView、IPagedCollectionViewですね(・∀・)
ICollectionViewの定義はこんなんですが。

public interface ICollectionView : IEnumerable, INotifyCollectionChanged
{
    event EventHandler CurrentChanged;
    event CurrentChangingEventHandler CurrentChanging;

    bool Contains(object item);
    IDisposable DeferRefresh();
    bool MoveCurrentTo(object item);
    bool MoveCurrentToFirst();
    bool MoveCurrentToLast();
    bool MoveCurrentToNext();
    bool MoveCurrentToPosition(int position);
    bool MoveCurrentToPrevious();
    void Refresh();

    bool CanFilter { get; }
    bool CanGroup { get; }
    bool CanSort { get; }
    CultureInfo Culture { get; set; }
    object CurrentItem { get; }
    int CurrentPosition { get; }
    Predicate<object> Filter { get; set; }
    ObservableCollection<GroupDescription> GroupDescriptions { get; }
    ReadOnlyObservableCollection<object> Groups { get; }
    bool IsCurrentAfterLast { get; }
    bool IsCurrentBeforeFirst { get; }
    bool IsEmpty { get; }
    SortDescriptionCollection SortDescriptions { get; }
    IEnumerable SourceCollection { get; }
}

カスタムページングに関連するのは、CanSort、SortDescriptions、Refresh()/DeferRefresh()のあたり(・ω・)
ICollectionViewの実装をDataGridにバインドしてソートをすると、DeferRefresh()が呼び出されます。
DeferRefresh()は更新遅延用のメカニズムなので、IDisposable.Dispose()内でRefresh()メソッドをコールバックするオブジェクトを返してあげればOK。
っで、Refresh()内ではイベントをあげて、ソート条件にあったデータの取得処理を呼び出し、コレクションを再構築してあげるっと。
ソートで使用する列や昇順降順はSortDescriptionsプロパティを参照、っと。


っで、ICollectionViewの実装としてはObservableCollectionを継承したクラスを作る方向で(・ω・)
CurrentItem、CurrentPositionに対応するための現在位置のプロパティを用意して、コレクションの操作時にはその情報も更新して。
CanFilter、CanGroupのあたりは、とりあえずソートに対応するだけであればfalseを返す実装でOK。
あとは、MoveXxx()を実装して、CurrentChanged、CurrentChanging及びOnPropertyChanged()を適切に呼び出してあげれば、オンデマンドでのデータ取得に対応したコレクションの完成っと。


更にページングに対応するためには、IPagedCollectionViewも実装(・ω・)
IPagedCollectionViewの定義はこんなんですが。

public interface IPagedCollectionView
{
    event EventHandler<EventArgs> PageChanged;
    event EventHandler<PageChangingEventArgs> PageChanging;

    bool MoveToFirstPage();
    bool MoveToLastPage();
    bool MoveToNextPage();
    bool MoveToPage(int pageIndex);
    bool MoveToPreviousPage();

    bool CanChangePage { get; }
    bool IsPageChanging { get; }
    int ItemCount { get; }
    int PageIndex { get; }
    int PageSize { get; set; }
    int TotalItemCount { get; }
}

IPagedCollectionViewの実装をDataPagerにバインドすると、ページの変更時にはMoveToXxx()が呼び出されるので(・ω・)
ICollectionViewの実装にIPagedCollectionViewも実装してあげて、MoveToXxx()の中でRefresh()を呼び出すようにすれば、ページングもオンデマンドで行えるようになるっと。


っで、リンク先からはその実装例がダウンロードできますね(・∀・)
ICollectionView及びIPagedCollectionView実装のPagedSortableCollectionViewの使い方はこんなんです。


まずViewModelをこんな感じで用意して。

public class HogeViewModel
{
    public PagedSortableCollectionView<Hoge> DataList { get; private set; }

    public int PageSize
    {
        get { return DataList.PageSize; }
    }

    public HogeViewModel()
    {
        DataList = new PagedSortableCollectionView<Hoge>();
        DataList.OnRefresh += new EventHandler<RefreshEventArgs>(DataList_OnRefresh);
        GetData();  // 初期データ取得
    }

    // DataGrid、DataPagerでの操作からこのハンドラが呼び出される
    private void DataList_OnRefresh(object sender, RefreshEventArgs e)
    {
        GetData();
    }

    private void GetData()
    {
        // 下記の条件を元に検索
        int take = DataList.PageSize;
        int skip = DataList.PageIndex * DataList.PageSize;
        foreach(SortDescription sortDesc in DataList.SortDescriptions) { ...  }

        // 本当はここで非同期通信開始
...
        // 完了ハンドラでデータ更新
        DataList.Clear();
        foreach (Hoge hoge in list) {
            DataList.Add(hoge);
        }
        DataList.TotalItemCount = count;
    }
}

DataGrid、DataPagerとはこんな風にバインディング

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Grid.DataContext>
        <vm:PeopleViewModel />
    </Grid.DataContext>
    <data:DataGrid x:Name="dataGrid"
                   AutoGenerateColumns="True"
                   Grid.Row="0"
                   ItemsSource="{Binding DataList}" />
    <data:DataPager x:Name="dataPager"
                    Grid.Row="1"
                    PageSize="{Binding PageSize}"
                    DisplayMode="FirstLastPreviousNext"
                    IsTotalItemCountFixed="True"
                    Source="{Binding DataList}" />
</Grid>

これで、カスタムソート/ページングしたデータの取得をオンデマンドで行う仕組みができました(・∀・)
将来のWCFはRESTfulということですが、このあたりのサポートも強化されると嬉しいかな〜(・ω・)

*1:サンプルレベルのものだと、画面初期表示に必要なデータを取得するようなものしかなかったりしてあれですが(´д`;)

仕事の成果を流用して趣味的な監視アプリケーションを作成メモ

放置していたけど、たまには雑記を書いてみたり(・∀・;)
最近、vSphere SDKを叩いたり、運用監視系のツールを作ったりもしていたので、その成果を流用して個人的に作った監視アプリケーションについて書いてみます。

システム概要

さて、開発や保守用途でVMを使うのは一般的になりつつある今日この頃ですが(・∀・)
VMの台数が増えてくると、稼働監視やリソースの使用状況のチェックも必要になってきます(・ω・;)


プライベートクラウドとか、会社のちゃんとした環境であれば、お金を出して稼働監視ツールを導入したりしますが。
自分達で勝手に作っている開発環境であれば、VMホストも無料のESXiだったり、監視ツールOSSのものを使用したりと言うことが多いと思います(・ω・)


っで、稼働監視の方法についてですが、VMゲストのWindowsLinuxについては、稼働監視ツールのエージェントをインストールして、情報収集を行うかと思います。
しかし、ESXiのホストについては、エージェントが対応していないケースがほとんどだと思います。
Linuxベースではあるので、staticな感じで無理矢理コンパイルしてみたり、スクリプトベースのエージェントもどきを作ってみるという手も無くはないですが(´д`;)
でも、そういった小細工はしなくても、ESXiが公開するWebサービスから各種パフォーマンスカウンターの値(VMware vSphere Clientのパフォーマンスタブで表示できる値に同じ)を取得できるので、その値を使用した稼働監視なら行えます(・∀・)


また、パフォーマンスカウンターについてはゲストの値も取得できるので*1、これらの値を収集してWebで表示する簡易監視アプリケーションを作ってみました(・∀・)

システム構成

概略図はこんなんです(・ω・)

ESXiが公開するWebサービスから、パフォーマンスカウンタを定期的に取得するアプリをJavaで作成して。
このアプリを、Linux上でデーモンとして動作させて、取得した各種値はMySQLに保存しています。


また、MySQLに保存した値から、稼働情報のダッシュボード表示と、パフォーマンス値のグラフ表示を行うアプリケーションをASP.NET MVCで作成して、Windows上で稼働させています(・ω・)


…っで、なんかJavaも.NETも使ったり、Linux上でもWindows上でもアプリが動いていたりしますが、本質的にはこんな構成にする必要はありません(´д`;)
このシステムと同様の事はJava/Linuxオンリー、あるいは.NET/Windowsオンリーな構成でも構築可能です。


単に、仕事でやったことの成果を流用したり、開発環境に相乗りさせているため、こんな構成になっているだけです(・∀・;)
自分は最近、JavaVMwareWebサービスを叩いたり、.NETでグラフ表示ということをやっていたので、その成果をそのまま流用するため、こんな構成になっているのでした(´д`;)

Webアプリケーション

っで、作成したアプリケーションですが、ホームを開くと下記の様なダッシュボードが表示されます。

これを見せた人からは、EVAっぽいとか、カッコイイwwwとか笑われましたが、まあ、ゼロ年代的なアニメやゲームっぽいものは意識しました(・ω・)
Webベースで単純に作って、Ajaxによる定期更新をしているだけなので、それっぽく見えるのは第一印象だけだったりしますが(´д`;)
本当は、状態が変わるときにアニメーションしたり、状態が一斉に警告になった時に挿入歌*2が流れたりすると、バカっぽくてもっとカッコイイ感じになりますが(^Д^)


っで、表示内容についてですが、各箱がVMホスト/ゲスト(最上段がホスト、その下がそこにぶらさがっているゲスト)を表していて、状態によって表示される文字や色が変わります。
状態としては稼働(RUNNING)、注意(WARNING)、警告(ALERT)、停止(STOPPED)、消失(LOST)という感じで。
ちなみに、このアプリでチェックしているのはCPU使用率、メモリ使用率、ディスク使用率だけですが、チェックする項目や閾値は設定で変更できるようにしています。


そして各箱をクリックすると表示されるのが、以下のグラフになります。

このグラフの値は、VMwareWebサービスを使ってパフォーマンスカウンタから取得した物ですが、ディスク使用量や稼働VM数などの情報については、インベントリ情報などから計算した値です。
この辺の値の計算も、プラガブルな実装になっていて、計算式クラスを増やせば任意の項目を追加できるような仕組みにはしています(`・ω・´)

仕事の成果の流用:パフォーマンス収集

っで、この監視アプリを作るために流用した、仕事の成果についても少し。


最近、VMwareWebサービスを使ってパフォーマンス収集みたいな事を仕事でやっていたんですが。
この辺、情報が少なくて(特に日本語の情報は皆無で)ちょっと苦労しました(´д`;)
公式のProgramming Guideに一通りの事はのっているんですが、個人的にはちょっとわかりにくい感じがして(´・ω・`)
もっとサンプルソースも欲しいんだけどということで、結局この書籍を購入したのでした。

VMware VI and vSphere SDK: Managing the VMware Infrastructure and vSphere

VMware VI and vSphere SDK: Managing the VMware Infrastructure and vSphere

もっとも、書籍が届く前になんとかなっちゃったんですけどね(´・ω・`)


ちなみに、稼働情報の収集に使用しているのはVimPortType.retrieveProperties()とVimPortType.queryPerf()の2つです。
まずは、retrieveProperties()でHostSystem、VirtualMachine、Datastoreの情報を収集して。
その後、ホストと各VMについては、queryPerf()により各種パフォーマンスカウンタ値を取得して。
パフォーマンスカウンタから直接取得できないような値については、取得したインベントリ情報とパフォーマンスカウンタ値から計算式クラス*3で2次計算というような事をしています(・ω・)


っで、同じようなことをやってみたい人は、とりあえず上記の書籍を購入することをお勧めします。
英語やvSphere SDKのオブジェクトモデルがよくわかんなくても、各処理のサンプルソースが載っているので、それを見ていけばなんとかなるんじゃないかと思います(・∀・)

仕事の成果の流用:グラフ(チャート)表示

グラフ表示も、ちょっと前に作った物の流用です(・ω・)
要は、RRDToolもどきの、.NET製のビットマップ作成ライブラリです。
ソースの構成は下記の様な感じで。

GraphBuilderがビットマップ作成のコアで。
サイズ、マージンにフォントや色なんかのプロパティを設定して、下記のようなIGraphHistoryのListを渡してやると、その内容に応じたグラフを作ってくれるという作り。

public interface IGraphHistory
{
    DateTime Clock { get; }
    decimal Value { get; }
}

っで、単にグラフのビットマップを作るだけなら単純な話なんですが、各パフォーマンス値によって目盛りのふりかたやスケーリング、グラフの描画方法(線、塗りつぶし)を変えるとなるとやっかいになってきて(´д`;)
その辺をStrategyで実装しているのが他のファイルになります。
っで、今回のVM用のグラフ表示では、それら各種Strategyを下記の様な定義で使用しています。

new GraphDef()
{
    No = 1,
    CounterId1 = Counter.CpuUsage,
    Display = "CPU使用率",
    Render = new LineRender() { LineWidth = 1.7f },
    Range = new FixRange( 10000 ),
    Separator = new FuncSeparator( 1000, _ => _ + 1000 ),
    TextFormatter = new NumTextFormatter() { Unit = "%", NumDigits = 2, Divisor = 100 },
    SeparateTextFormatter = new NumTextFormatter() { Divisor = 100 },
},      
...
new GraphDef()
{
    No = 5,
    Display = "ネットワーク受信/送信",
    CounterId1 = Counter.NetRecv,
    CounterId2 = Counter.NetSend,
    Render = new LineRender() { LineWidth = 1.7f },
    Range = new SizeRange(),
    Separator = new FuncSeparator( 16, _ => _ * 2 ) { Separets = 8 },
    TextFormatter = new SizeFormatter() { Suffix = "B/s", NumDigits = 1 },
    SeparateTextFormatter = new SizeFormatter() { NumDigits = 1, OptionalDotZero = true },
},
new GraphDef()
{
    No = 6,
    Display = "稼働時間",
    CounterId1 = Counter.SysUptime,
    Render = new FillRender(),
    Range = new TimeRange(),
    Separator = new TimeSeparator(),
    TextFormatter = new TimeFormatter() { NumDigits = 2 },
    SeparateTextFormatter = new TimeFormatter(),
},
new GraphDef()
{
    No = 7,
    Display = "VM総数/稼働数",
    CounterId1 = Counter.VmTotal,
    CounterId2 = Counter.VmActive,
    Render = new LineRender() { LineWidth = 1.7f, LineType = LineType.Max },
    Range = new CeilRange( 5 ),
    Separator = new FuncSeparator( 1, _ => ( _ == 1 ? 5 : _ + 5 ) ),
    TextFormatter = new NumTextFormatter() { Unit = "vm", NumDigits = 1, OptionalDotZero = true },
    SeparateTextFormatter = new NumTextFormatter(),
},

CPUを例に取ってみると、描画は線(LineRender)で、上限値は100%の固定(10000というのは、VMwareが使用率を0.01%単位の整数で返すから)、横軸の線は10%(1000)単位で描画して、グラフ下部の現在値や平均値については値を100でわったものに%をつけて描画、っというような内容になります(・ω・)
他の例で言えば、ネットワークの送受信なんかは2の倍数単位でスケールの計算と、K、M、Gとかの単位で文字を描画しますし。
稼働時間は秒、分、時、日(d)〜等の人間が見やすい単位でスケール計算、VM数については5単位でのスケール計算という風な感じになっています。


まあ、このライブラリについては、汎用化するにはもう少し各種プロパティの整理が必要というのと、名称についてもちょっと見直しが必要かなという感はありますが(´・ω・`)

まとめ

っということで、仕事の成果を流用してVMの稼働監視を行うアプリケーションができたのでした。
若干ネタ的な部分があったり、正直実用性は?な部分もありますが。
だって、これとは別にMuninやZabbixも動かしてるし(・∀・;)
まあ、ダッシュボードを見せて、笑いを取るために作ったという意味合いが強いので、そんなんで良しとします。


っで、あとちょっと思ったのだけど、普段事務システムしか作ったことが無いような人も、たまにはこういうおもちゃ(?)を作ってみるのも良いと思うのよね(・ω・)
なぜかというと、こういうものを作るためのノウハウというのは、事務システムを作っているだけでは学べない部分が多いから。
例えばデザパタの知識なんかも、ありがちな事務システムとか作る上では、ぶっちゃけ必要なかったりもますが。*4


でも、だからと言って、そういう知識が必要無いわけではなくて。
むしろこれからの時代は、アドホックなシステム構築のためにも、そういった知識は必須というか常識になるわけで、こういうのをサクサクっと作れない人は、危機感を持った方が良いと思うのよね(・ω・;)
っということで、みんな趣味でミドルやフレームワークを実装してみるのだ、つって(・∀・)

*1:補足すると、この値はホストがゲストに割り当てている値の意味合いなので、例えば同じCPU使用率と言っても、Webサービスから取得できる値と、ゲストOS上で認識できる値では、値も意味合いも異なりますが(・ω・)

*2:警告灯がわりに(・∀・;) 個人的にはJAM Projectあたりを希望(・∀・)

*3:実装としては、稼働VM数/VM総数を計算するHostVirtualMachineCalculatorクラス、DatastoreやVMのDisk情報からディスク使用量等を計算するHostDiskCalculator、GuestDiskCalculatorクラス等を用意

*4:その代わり、むしろアーキテクチャパターンはちゃんと学べ(`・ω・´)