【注意】 この文書は、Google Wave Federation Protocol ウェブサイトで公開中のホワイトペーパー「Google Wave Federation Architecture」を、クリエイティブ・コモンズの Attribution(表示)3.0 Unported ライセンス に基づいて日本語に翻訳したものです。
原文が更新された場合にはこの文書の内容との差異が生じる可能性があり、また翻訳に間違いや不適切な表現が含まれていることも考えられますので、修正が必要とみられる点がありましたら、翻訳者へのメールまたは当サイトへのコメント投稿などによりご連絡いただくことを歓迎いたします。
Google Waveは、同時編集と低レイテンシな更新処理をサポートするホスト型ドキュメント(Waveと呼びます)に基づく、新たなコミュニケーションとコラボレーションのプラットフォームです。このプラットフォームにより、これまでにない便利で効率的な方法でのコミュニケーションや共同作業が可能になります。私たちはこれらのメリットを wave.google.com のユーザに提供すると共に、Waveというものを誰もが共有できるオープンなプラットフォームにすることで、それらのメリットを他のすべての人々とも分かち合いたいと考えています。私たち以外のみなさんにも、自己利用のためのツールや他のユーザ向けのサービスとして、Waveサーバを立ち上げWaveプロバイダになっていただき、Waveを“連携させる(federate)”、すわなち他のWaveプロバイダや wave.google.com と共有していただくことを歓迎します。そうすれば、別々のWaveプロバイダのユーザ同士でも、共有したWaveでのコミュニケーションやコラボレーションができることになります。これから、インターネット上のWaveプロバイダ間でWaveを連携させるための Google Waveフェデレーションプロトコルを紹介します。
このドキュメントは、 Google Waveテクノロジのさまざまな要素(データモデル、オペレーション変換、クライアント-サーバプロトコル)がどのように組み合わさってWaveサービスが実行されているのか、Waveサービスのプロバイダ同士がなりすましを防ぐためのGoogle Waveフェデレーションプロトコルによる暗号化対策を用いてどのように通信を行うのかについて、その概要を説明します。これらの要素はすべて当サイトにある関連ドキュメントでさらに細かく解説されているため、詳しくはぜひそれらを参照してください。本ドキュメントの主題はあくまで連携に絞られており、Waveサーバ間通信用のフェデレーションプロトコルの説明は含みますが、クライアントとWaveサーバとの通信に用いるクライアント-サーバプロトコルは扱いません。それでもなお、このドキュメントではWaveの連携について徹底的に説明し尽くすところまで行っていません。Waveの連携に関わる要素としてここでカバーできなかったものの中で、アタッチメント、グループ、コンタクト、プレゼンスはとりわけ重要です。
Google Waveフェデレーションプロトコルを用いれば、誰でもWaveプロバイダになって、他の人々とWaveを共有できます。組織がそのメンバー専用のWaveプロバイダとなったり、個人が自分専用または家族向けのWaveプロバイダとしてWaveサーバを立ち上げたり、インターネットサービスプロバイダがメール、IM、FTPなどの補助的サービスとなるWaveサービスを契約ユーザに提供したりという例が考えられます。そうなれば、wave.google.com は数多くのWaveプロバイダの一つということになります。
Waveプロバイダは、インターネット上のドメイン名によって識別されます。
Waveユーザは、ユーザ名とWaveプロバイダのドメイン名から成る、メールアドレスと同じ形式(ユーザー名@ドメイン名)のWaveアドレスを所有します。Waveアドレスは、グループ、ロボット、ゲートウェイ、その他のサービスにも割り当てられます。グループのアドレスは複数のWaveアドレスの集合を指すもので、メーリングリストのアドレスによく似ています。ロボットは、自動化されたWaveへの参加者です(robots APIを参照)。たとえば、翻訳ロボットやチェスの対戦用ロボットなどがあります。ゲートウェイは、Waveと他の通信/共有プロトコル(メールやIMなど)との間で必要な変換処理をします。ここから先の説明では、ロボットやゲートウェイなどを含むサービスのアドレスは対象としません。連携の面に関しては、それらはほとんどユーザのアドレス同様に扱われるからです。
Waveユーザは、利用するWaveプロバイダを経由してすべてのWaveにアクセスします。一つのWave上に異なるWaveプロバイダからの参加者がいる場合、どのWaveプロバイダもそのWaveのコピーを保持し、それぞれのユーザに提供します。Waveプロバイダは、これから説明するGoogle Waveフェデレーションプロトコルを用いて、そのWaveの更新情報を互いに共有します。どのWaveユーザについても、そのユーザのドメインで(Cookieやパスワードなどによる)認証を行い、ローカルでのアクセスコントロールを実施することが、Waveプロバイダの責任となります。
Waveは、「Wavelet」の集合から成り立っています。
Waveletにアクセスすると、ユーザはそのWaveletへの参加者と呼ばれます。
各Waveletには、参加者リストと、そのコンテンツとなるドキュメント一式があります。一つのWaveの中で、Waveletごとに異なる参加者リストを持つこともあります。Waveletのコピーは、そのWaveletへの参加者が最低1名はいるWaveプロバイダすべてが共有することになります。それらのWaveプロバイダのうち、そのWaveletの確定的なコピーを持つ特定Waveプロバイダが存在します。この特別なプロバイダが、そのWaveletを「ホスティング」しているという言い方をします。
ユーザがWaveを開くと、Waveの「ビュー」が現れます。つまり、そのユーザが(直接的に、またはグループへの参加によって間接的に)参加者となったWaveに含まれるWaveletsの集まりです。同じWaveを開いても、ユーザごとにWaveビューの見た目が違うのが普通です。たとえば、そのWaveの既読/未読状態のようにユーザごとに異なるデータは、そのユーザのみを参加者とするユーザデータWaveletに保管されます。ユーザデータWaveletは、そのユーザのWaveビューにしか現れません。もう一つの例となるのが、Wave内でのプライベート返信です。これは限定された参加者リスト向けのWaveletになります。このプライベート返信Waveletは、リスト内のユーザのWaveビューにしか現れません。
Waveは、グローバルなレベルでユニークとなるWave IDによって識別されます。これは、ドメイン名とID文字列の組み合わせです。このドメインが、Waveが作成されたWaveプロバイダを指します。
Waveletは、そのWave内でユニークとなるWavelet IDを持ちます。Wave IDと同じく、Wavelet IDもドメイン名とID文字列の組み合わせです。Wavelet IDに含まれるドメイン名は、特別な役割を果たします。それがWaveletをホスティングするWaveプロバイダを指すからです。Waveletは、それを作成した参加者が利用しているWaveプロバイダによってホスティングされます。WaveletをホスティングするWaveプロバイダは、Waveletにおけるオペレーション変換とWaveletオペレーションの適用と、Waveletへの参加者すべてのWaveプロバイダでの更新処理に責任を持ちます。これについては、後ほどWaveサーバについてのセクションでも触れます。更新処理はWaveletオペレーションであり、更新が同時発生した場合にはオペレーション変換を用いてバージョンの食い違いを解決します。
同一Wave内のWaveletを、それぞれ異なるWaveプロバイダでホスティングすることもできます。たとえば、ユーザデータWaveletは必ずそのユーザのWaveプロバイダでホスティングされ、Wave内の他のWaveletがどこでホスティングされているかは関係ありません。実のところ、ユーザデータは連携されない(つまり他のWaveプロバイダとは共有されない)のです。
もう一つの例は、プライベート返信Waveletです。そのごく単純なケースとなるのが、プライベート返信への参加者全員が同じWaveプロバイダを経由している場合です。この場合、Wave内の他のWaveletがどこでホスティングされていようと、そのWaveプロバイダはプライベート返信Waveletを他のWaveプロバイダと共有しません。
Waveプロバイダは、ネットワーク接続された1台以上のサーバで稼働するWaveサービスをオペレーションします。
Waveサービスの中心的要素となるのは、Waveletオペレーションを保管するWaveストアと、オペレーション変換によってWaveletオペレーションの解決を行ったり、Waveストアに対してWaveletオペレーションの読み書きを行うWaveサーバです。通常、WaveサービスはそのWaveサービスフロントエンド(Google Wave Data Model and Client-Server Protocol(日本語訳)を参照)に接続するWaveプロバイダのユーザをサービス対象とするので、ここからはそれを前提としてWaveサービスのアーキテクチャを説明していきます。さらに大切なのは、Waveサービスが連携を目的として他のWaveプロバイダ経由のユーザとWaveを共有するため、それらのWaveプロバイダのサーバと通信を行うことです。Waveサービスはそのためにフェデレーションゲートウェイとフェデレーションプロキシという2種類のコンポーネントを利用します。次のセクションでそれらを解説します。
WaveプロバイダのWaveサーバは、ローカル参加者、つまり自ドメインの参加者に対してWaveビューを提供します。前述の通り、WaveletのコピーはそのWaveletへの参加者が利用するすべてのWaveプロバイダに配信されます。プロバイダ側では、Waveletのコピーを「ローカル」でも「リモート」でも扱うことができます。これら2種類のWaveletのコピーを、それぞれ「ローカルWavelet」「リモートWavelet」と呼ぶことにします(いずれの場合も、それが指すのはWaveletのコピーであり、Waveletそのものではありません)。Waveビューは、どちらの種類のWaveletコピーでも同時に保持することができます。
あるWaveプロバイダにおいて、ローカルWaveletとは、そのプロバイダで作成されたもの、すなわち、そのWaveletプロバイダに属するユーザが作成したものを意味します。Waveサーバは、ローカル参加者または他のWaveプロバイダ経由のリモート参加者から送信されたWaveletオペレーションの処理に責任を持ちます。Waveサーバはオペレーション変換を用いて送信されたWaveletオペレーションに相対的な順序を付け、バージョン管理を行います。また、それらのオペレーションをローカルWaveletに反映する前に、その検証を実行します。
リモートWaveletは、他のWaveプロバイダによってホスティングされています。Waveサーバはローカルにキャッシュされたそのコピーを保持し、ホスティング元のWaveプロバイダから送信されるWaveletオペレーションによって内容を更新します。ローカル参加者がリモートWaveletにWaveletオペレーションを送信すると、Waveサーバはそのオペレーションをホスティング元プロバイダのWaveサーバに転送します。変換と適用が行われたオペレーションが返ってくると、キャッシュされているコピーにそれが反映されます。ローカル参加者を読み込むためのアクセスは、ホスティング元のWaveプロバイダへの行き来を必要とせず、キャッシュされているコピーから実行されます。
ローカルかリモートかを問わず、WaveletはすべてWaveサーバ上に永続的に存在するWaveストアに保管されます。
Waveプロバイダは、ローカルWaveletよりも“上流(upstream)”にあり、リモートWaveletよりも“下流(downstream)”にあるという言い方をします。
Wave サービスは、他のWaveプロバイダと通信する際に、フェデレーションゲートウェイとフェデレーションプロキシというコンポーネントを用います。
フェデレーションゲートウェイは、ローカルWaveletオペレーション、つまりローカルWaveletに対する操作を伝達します:
フェデレーションプロキシは、リモートWaveletオペレーションを伝達するもので、WaveプロバイダのコンポーネントとしてリモートWaveプロバイダのフェデレーションゲートウェイと通信します:
上流のWaveプロバイダのフェデレーションゲートウェイは、下流のWaveプロバイダのフェデレーションプロキシに接続して、上流のWaveプロバイダがホスティングするWaveletオペレーションをプッシュするのです。
フェデレーションプロトコルは、ゲートウェイからプロキシへのオペレーション到達の信頼性を確保する以下のようなメカニズムを備えています。
フェデレーションゲートウェイは、各リモートドメイン向けのオペレーション送信キューを(永続的ストレージ内で)管理します。オペレーションは、受信側のフェデレーションプロキシによって到達確認が行われるまでキューに留まります。フェデレーションゲートウェイは継続的に接続の確立を試み、接続が失敗した場合には(指数関数的再送処理(exponential backoff)によるリトライを行って)再接続しようとします。接続が確立すると、フェデレーションゲートウェイはキューに溜まっているオペレーションを順次送信していきます。受信側のフェデレーションプロキシは、バックチャネル経由で到達確認を送信側のフェデレーションゲートウェイに送り返し、送信側ではそれを受け取るたびに確認済みのオペレーションをキューから取り出します。
では一つの事例として、(acmewave.com, conv+090528) というWavelet IDを持つ、WというWaveletがあるとしましょう。acmewave.com がドメインで、"conv+090528" がID文字列(ここではその構造は問いません)です。このWavelet IDを見れば、WがAcmewaveのWaveプロバイダによってホスティングされていることが分かります。Wへの参加者として、 federati.comという別ドメイン経由の feddy@federati.com というメンバーがいるとします。
ローカル参加者からもリモート参加者からも同様に送信される、Wに対するすべてのWaveletオペレーションは、変換後にWに反映され、AcmewaveのWaveプロバイダによってローカルWaveストアに保管されてから、それらの反映済みオペレーションをプッシュするフェデレーションゲートウェイへと渡されます。そのためにAcmewaveのゲートウェイは、Federatiのフェデレーションプロキシへの接続を確立し、それを介してオペレーションを送信します。
場合によっては、受信側が送信側から過去のオペレーションを送ってもらうようリクエストする必要も生じます。よくある例となるのが、受信したオペレーションの対象となるWaveletについて、それ以前のオペレーションを一部しか持っていない場合です。(このケースに当てはまるかどうかは、反映済みオペレーションに連続したバージョン番号が振られているので、すぐに分かります。)この場合、受信側のフェデレーションプロキシはWaveletをホスティングしているドメインに接続し、過去のオペレーションで足りない分をリクエストします。(Waveサーバが削除用Waveletのオペレーション履歴にそういう穴を空けてしまう一因となるのは、ある時点(t1)でそのドメインからは誰もWaveletに参加しておらず、それ以降の別の時点(t2)でそのドメインから参加者が加わったという場合です。ホスティング元のフェデレーションゲートウェイは、それ以降のオペレーションすべてをフェデレーションプロキシに転送することになる新しい「AddParticipant」オペレーションを送信して応答しますが、後者は自分で以前のオペレーションをさかのぼってリクエストしなければなりません。)
同様に、ユーザがリモートWaveletにオペレーションを送信することもできます。すなわち、フェデレーションプロキシがリモートのフェデレーションプロキシに接続して、そのWaveサーバにオペレーションを送信できるようにするわけです。
たとえば、Federatiがホスティングする(つまり、Wavelet IDのドメイン部分が federati.com となっている)別のWaveletがあり、そこにacmewave.comからの参加者が一人いるとしましょう。その場合も、FederatiのゲートウェイとAcmewaveのゲートウェイは互いに通信することになります。
フェデレーションゲートウェイとプロキシの間で用いられるネットワークプロトコルを、Google Waveフェデレーションプロトコルと呼びます。これは、インスタントメッセージングプロトコルであるXMPPのオープンな拡張(extension)です。このフェデレーションプロトコルが用いている、XMPPのとびきり便利な機能としては、IPアドレスやポートの自動検出、SRVレコードの利用、TLS認証、接続の暗号化などがあります。『Google Wave Federation Protocol』も参照してください。
プロトコルの仕様は、フェデレーションプロトコルを用いて接続しているWaveプロバイダが、暗号技術的に安全なTLSメカニズムを用いた認証を行うことを必須条件としています。さらには、Waveプロバイダ間のトラフィックをTLSで暗号化することを推奨しています。クライアント-サーバプロトコルとフェデレーションプロトコルは、エンドユーザ間でのエンドツーエンド型認証や暗号化には対応していません。Waveプロバイダがエンドユーザの認証を行うべきであり、またユーザ接続も暗号化することが推奨されます。両者を組み合わせ、Waveサービス同士でもユーザとWaveサービスの間でも安全な接続を確立すれば、エンドツーエンド型のセキュリティを納得のいくレベルで提供できます。
Jochen Bekmann, Michael Lancaster, Soren Lassen, David Wang: Google Wave Data Model and Client-Server Protocol(日本語訳)
David Wang, Alex Mah: Google Wave Operational Transformation
Daniel Berlin: Google Wave Federation Protocol
Lea Kissner and Ben Laurie: General Verifiable Federation