NoSQL サーバ Cassandra を Ubuntu にさっくりとインストールする
もともと Debian 向けなんだけど、Ubuntu 10.04 でも上手くいったっぽいのでメモ。
まず、/etc/apt/sources.list.d/cassandra.list というファイルを作る。内容は以下のとおり。
deb http://www.apache.org/dist/cassandra/debian unstable main deb-src http://www.apache.org/dist/cassandra/debian unstable main
次に公開鍵のインポート。以下の二つのコマンドを打つ。
gpg --keyserver wwwkeys.eu.pgp.net --recv-keys F758CE318D77295D gpg --export --armor F758CE318D77295D | sudo apt-key add -
最後に cassandra のインストール
sudo apt-get update sudo apt-get install cassandra
設定は /etc/cassandra 起動オプションは /etc/default/cassandra をいじりましょう。
ウォーターフォールはアジャイルよりも難しい
きっと同じような記事を書く人がたくさんいるんだろうなぁと思いつつ。
アジャイルはウォーターフォールよりも難しい | 日経 xTECH(クロステック)
↑こちらの記事に触発されて、私がウォーターフォールやりながらアジャイルでやりてぇと思ったときの経験を書いてみる。
難しさ(1)落ちない水。隠れた溯上用水路
ウォーターフォールとは、滝のことです。各プロセスが手戻りすることなく、次々にこなされている様が、また、ガントチャートなどで書き表わした場合の様がその滝のように見えますね。
さて、このプロセスって、ちゃんと予定通りこなすことってできるんでしょうか?
まず無理でしょう。なぜなら、見積り工期の根拠が乏しいからです。ふたを開けてみたら「思ったより時間がかかった」という経験を持っている方は少なくないでしょう。
また、やってみたら「この仕様じゃダメじゃね?」となったこともあるか思います。と言いますか、ないことのほうが少ないでしょう。しかし、ウォーターフォールでは「もどっちゃダメ」なんです。ならどうするかというと、溯上のために関のわきに作られた水路を鮭が泳ぐように、「こっそり」誰かが後戻りするのですね。
こんなことやってるのに「やっぱり大規模開発にはウォーターフォールです(キリッ」とか言ってるんですね。戻ってんじゃん! デスマ要員が泣きながら戻ってんじゃん!
難しさ(2)ドキュメントの粗製濫造
サービスインして5年。
運用SE「こういうときどうなるんでしたっけ?」
開発PG「えーっと、それはソース見ないとわかんないですね」
あれ? じゃあ、なんでドキュメント作ったの?
さらに5年。
新開発PG「リプレースするんだけど、これの仕様書ないの?」
運用SE「ないっすよ」
あれ?
難しさ(3)円滑なコミュニケーション
偉いSE「ということで、難しくてもこのままやってね」
下っ端PG「そうはいってもマンパワーに限りがあるし(^ω^;」
偉いSE「いまさら手法変えるとか、手戻りできないんだよ」
下っ端PG「……(^ω^;(氏ね)」
3歳前だって多少の旅行はいいのではないか?
いつもとは毛色の違う記事です。
↑こちらの記事を読ませていただいたのですが、母親は寝坊するなというのには賛同します。私は二児の父になりましたが、母親ばかりでなく父親もだらしないところは見せていられないなと自らを律したいと常々思っております。
ただ後半のくだりについては多少賛同しかねました。特に以下のくだりです。
知能の面についても、三歳にならないうちは言葉と時間をしっかりとは覚えていないので、海水浴や動物園や温泉に行ったことが記憶として残って、その後の知能の発達の役に立つということはほとんど期待できません。
真夏のひまわり 「母親は朝寝坊するな」の一喝に思うこと
私は、2歳のときの記憶が今でもあります。私の父もそうらしいです。なので、うちの子もそうなんじゃないかと思いますし、言葉を覚える過程においても見たことがあるのとそうでないのではまったく違うと私は感じています。
他の子はどうかはわかりませんが、うちの子(もうすぐ3歳)はさまざまなものを連想ゲームのように結びつけます。今朝、私の母が天気予報を見て「今日は33度まであがるのか」といったら、うちの子はそれを聞いて「サンドイッチ」と言いました。「さんじゅうさんどイッチ」なんですね。
もうすぐ2歳になるというときに温泉に連れていったことがありますが、そこで水風呂を体験したのが影響したらしく、風呂がぬるいと「大きい風呂みたい」といいます。
好きな動物も、2歳半のときに動物園にいってから変わりました。明らかに彼の知能に影響をあたえている証拠ではないでしょうか?
結果論かもしれませんが、病気にもなっていません。ただ、私たち親としては旅行の際は子供の体力の消耗を考えて綿密に計画していきました。
たとえば、移動は車だけをつかったのですが、その車での移動時間は子供のいつものお昼寝の時間、ないしは「眠くなるパターン」に合うように計画しました。子供ですから、長時間じっとしているのは苦痛でしょうから、眠らせておけばストレスも最小限に抑えられると考えたからです(もちろん、チャイルドシートでの寝心地なんてたかが知れているのでふつうのお昼寝ほど体力を回復しないとも考えました)。
うちの子は、ほかの子より若干言葉が遅いようですが、おでかけの度に語彙や表現力が爆発的に変化するように見られます。この経験があると、いくら大先生のお話でも疑問を持たざるを得ないのです。
Wicket 1.4.10 リリース
先週 Wicket 1.4.10 がリリースされましたね。新たに Component クラスに onInitialize() メソッドと onConfigure() メソッドが追加されました。
onInitialize() は、これまでコンストラクタで行っていたような初期化処理を行うためにオーバーライドして使います。
なぜコンストラクタで行ってはいけないかというと、コンストラクタで行うとコンポーネントの相互参照ができないなど「インスタンス化の順序」が問題になることがあるからです。
onInitialize() は、Page オブジェクトに直接または親コンポーネントを経るなりして add された場合、ライフサイクルの最初に実行されます。
私は、Swing のようにイベントリスナを準備して継承を用いずにコンポーネントの機能を拡張できるようにコンポーネントをカスタマイズして使うことが多いのですが、これまでは初期化処理がイベント駆動にできずに多少不便を感じていました。これで初期化処理もイベント駆動にできるのでこの機能は歓迎しています。
onConfigure() は、onBeforeRender() を補完するものとなるでしょう。onBeforeRender() はデフォルトではレンダリングされないことが明らかな場合は実行されません。たとえば、setVisible(boolean) で false が渡された場合などです。
それに対して onConfigure() は、そのコンポーネントが属するページにリクエストがあれば必ず実行されます。そのため、例えば「リクエストされた時刻が17:00を過ぎていた場合のみ表示」といった処理が割りと簡単に書けます。
対価を払う
私の仕事で主に使う PC の OS は Ubuntu です。Windows も使います。PC でゲームをすることもあるので、プライベートでは Windows の割合が高くなりがちです。
そんな私は、さまざまなフリーソフトウェアを使わせていただいています。社内外で、私はさまざまな便利なフリーソフトを知っているやつと思われていることも少なくないです。
そんなある日、私にこんな質問がなげかけられました。
「ウィルス対策ソフトは何使っているの?」
私は、Windows での話だということはわかっていたので「ESET Smart Security を使っています」と答えました。するとその人はあからさまにがっかりしたような顔をしました。そして「君が有償のソフトを使ってるなんて珍しいね」と言われました。私はこれは非常に心外に思いました。
世間一般を眺めてみますと、「PC 好き」と呼ばれるような人はたくさんの便利なフリーソフトを知っていることが多いようです。このような人は、そうではない人には「タダでお得に PC を使い倒している」と見えるでしょう。
しかし、対価がゼロであることが真にコストゼロであるとは限りません。ちょっと使いにくいフリーソフトで悶々と3日かけて仕事するぐらいならば、1000円のシェアウェアを購入して2日で仕事を終えるほうがコストが低いということは言うまでもないでしょう。
ここでは「ESET Smart Security」なるソフトが良いか悪いかはおいておきますが、少なくともある時点の私のソフトウェア選定眼からすると、フリーウェアで出回っている同種のソフトよりも総合的なコストが低かったから私は使っていたわけです。
プロならばこいう視点は大切にしたいものです。
クライアント認証で大ハマり
とあるところに CentOS で構築した Web サーバを収めました。それは、LAN 内からしかアクセスできないのですが、そこの決まりでクライアント認証をしなければならなかったのでかように設定をしました。
ところが最近、これにつながらなくなりましてさあ大変。
まったく原因がわかりませんでした。
現象1 Linux からはつながる
このサーバ自身に入れておいた Firefox からは接続することができました。でも、お客様が使っているのは Windows。ここかはらなぜかアクセスできない。ブラウザは IE7。Firefox 3.0.x でも試してみたけどダメ。
現象2 再現できない(と思ってた)
仕方がないので、似たような環境を自社内に構築して確かめてみたら。上手くいく。と思っていたけど、試していたのは証明書と LAN 用に構築した CA のみで、ディレクトリ構造などは二の次にしておりまして、ディレクトリ構造も真似てみたら再現できました。
再現方法確定
Location ディレクティブでクライアント認証が必要なところを限定すると上手くいかないということが発覚。Googlability を挙げるために /etc/httpd/conf.d/ssl.conf の断片を載せときます。
<Location "/hoge/"> SSLVerifyClient require SSLVerifyDepth 1 </Location>
そして解決へ
どうも再ネゴシエーション脆弱性対応のため、サーバ側にあたったアップデートが原因らしい。そのため、RFC 5746 非対応のブラウザでは接続できなくなっていたようです。ということで、ブラウザを変えられない膠着した組織ではサーバ側でこの脆弱性対応をあえて無効にしなければ従来のように接続させることはできません。次の一文を /etc/httpd/conf.d/ssl.conf に書きましょう。
SSLInsecureRenegotiation on
その名のとおり「安全でない再ネゴシエーション」です。ご利用の際は十分な了解を得ましょう。
Wicket でこんな風にプロジェクトをすすめました
ちょっとした成功体験を紹介します。
どんなプロジェクトだったか
オフコン系の社内業務支援システムをWebベースに作り変えるプロジェクトでした。まだ全部終わってませんので過去形でいうのは適当ではありませんが。
コンポーネントの登録を省力化した
とにかくこの手のシステムは1画面あたりの項目数が多い。なので、コンポーネントの生成と登録をちんたら手組しているとラチがあきません。そこで私がとった方法は、Excelシートに項目名とコンポーネントの種類、Wicket ID、必須か否かや値の範囲などの簡単なバリデーション情報を書いて、それを POI で読み込んでソースを生成することでした。
はじめはコンポーネントの種類はまさしくクラス名で指定していたのですが、何度かバージョンアップを繰り替えして今では和名で指定しています。実際のクラス名とは別区XMLファイルで結びつけています。たとえば「テキストフィールド」と指定されたら TextField クラスを使うといった感じです。
生成するソースはページクラスではなく、MarkupWebContainer のサブクラスです(このプロジェクトではこれをワーキングペインと読んでいます)。ページクラスにこれをそのまま add して使ってもらいます。これに CompoundPropertyModel をむすびつけます(永続化には S2JDBC を使用しました)。すべてのコンポーネントは Wicket ID と同じ名前のメソッドで取得できるようにしました。たとえば、Wicket ID が hoge という RadioGroup コンポーネントの下にぶら下がっている fuga という Radio コンポーネントを取得するには以下のようにします。
String s = workingPane.hoge().fuga().getModelObject(); // モデルオブジェクト取得
独自コンポーネントを充実させた
前述の仕様をまとめていると、どんな UI コンポーネントが必要かが自ずから分かってきます。つまり、どんなビヘイビアを使うのかとか、どんなコンバータを使うのかとかです。こういうものは惜しげもなく新コンポーネントとして作ってしまいます。無名クラス(LinkとかButtonを利用する際に作りがちですよね)を作ったら負けぐらいの勢いで作っていきます。これによってさらに前述の Excel シートが書きやすくなります。
スーパークラスを充実させた
社内向の業務システム、特にオフコン、汎用機系を踏襲したようなものはとにかく画面がパターン化されています。そのため、スーパークラスを充実させるとかなりコーディングが楽になりました。たとえば、このプロジェクトも業務システムによくあるように画面下部にファンクションキーに対応するボタンがならんでいるのですが、ファンクションキーの F3 に対応するボタンが押されたら実行されるイベントは以下のように書けるようにしました。
@Override protected void onSubmitF3() { // 処理 }
また、画面によってボタンのラベルや有効化/無効化の設定は以下のように書けるようにしました。
f3().enabled(true); f3().setLabel("実行");
まとめ
今回のプロジェクトは、俗に言う「SE」的なポジションの人がいなかったように思えます。いるのは、仕様をよく知っている(仕様の決定権のある)プログラマ(ただし、Wicket はもちろん Java のコーディング力が特別高いわけではない)と比較的 Wicket を自在に扱える私のような(しかし仕様はよくわからない)人でした。そして、プログラマが「ここよく使うんだけどもっと簡単にならない?」というのを頻繁に挙げてくれて、それを私がフレームワーク化していくというような流れで開発していきました。
Wicket はよく Web プログラミングにオブジェクト指向を取り戻したと言われますが、私もそう思います。この Wicket の特徴のおかげでこのやりかたでうまく流れたのかなと思います。