ネーミングサービスとは?
ネーミングサービスは、OMGで規定されているサービスの1つで、ここに仕様がありますので詳細は、読んでいただく方がよいと思います。とはいっても、英語ですのでネーミングサービスに関して説明されているサイトが、ここ(TECHSCORE)にもあります。このサイトは、非常によく説明されていると思います。
ネーミングサービスとは、簡単にいえば、名前とCORBAオブジェクトのアドレス帳みたいなものです。これが何故必要かというと、CORBAの規格では、CORBAオブジェクト名のすべての名前の付け方を決めていません。言い換えれば、これはCORBAサービスを提供する人に任せているといえます。
とはいっても、任意のCOBRAオブジェクトに一意の名前を自動的に付けるのは非常に難しいので、UUIDのようにネットワーク上で一意性を保証する名前が、CORBAオブジェクトのIDを決めるのに使われることがあります。RtORBでもOpenRTM-aistでもCORBAオブジェクトやRTコンポーネントに対するIDは、e2fsprogsパッケージのUUIDライブラリで生成したものを使っています。
しかし、自動生成されたID(名前)は、規則性がない文字列になっています。そのため、自分が利用したいオブジェクトやコンポーネントがどういう名前になっているかを覚えておくのも、誰かに伝えるのも大変なので、その名前を管理するための仕組みがほしくなります。そのためのサービスがネーミングサービスです。
ネーミングサービスは、CORBAだけの話ではなく、ネットワーク上では他にも似たようなサービスがあります。それは、DNS(ドメインネームサービス)と言われるものです。皆さんは、インターネットでホームページを見ると思いますが、Yahooのサイトを見るときには、http://www.yahoo.co.jp のような URLというのを使うと思います。しかし良く考えてみると、ネットワークの中ではコンピュータに割り当てられているのは、192.168.0.1のような32ビットIPアドレスです。このアドレスと人間が覚えやすいような「名前(URL)」との対応付けが必要になります。これがDNSの提供するサービスです。このDNSがあれば、実際に提供するコンピュータがいつの間にか入れ替えられていても、我々ユーザには何の支障もなくサービスが受けられるということになります。DNSについてよくわからないという人は、小悪魔女子大生のサーバエンジニア日記を見ることをお勧めします。非常に分かりやすく書かれています。
この考え方と同じようにCORBAの世界でもネーミングサービスがあるのです。では、ネーミングサービスを提供しているがどこか探すのはどうしましょうか?
さすがにこれはCORBAの仕様でも決められています。通常は、ネームサーバーを自分のコンピュータ上で起動しておき、2809ポートでサービスをするとなっています。CORBAのURLでは、corbaloc::localhost:2809/NameService という風に書きます。このURLの意味は、自分のコンピュータ上の2809というポートでNameServiceというオブジェクトIDを持つCOBRAオブジェクトがあるという意味です。ここで分かると思いますが、NameServiceをするCORBAオブジェクトは、オブジェクトIDが仕様で予め決められています。
このCORBAオブジェクトに、自分の名前を登録したり、登録されているCORBAオブジェクトの一覧を取得したり、名前からCORBAのオブジェクトを検索し、その参照を教えてもらったりするサービスがあります。
自分のコンピュータ上で、このネームサーバーが起動しているかどうかは、''telnet localhost 2809'' というコマンド入力で正常になるかどうかで判断することもできます。
では、続いてCORBAのネーミングサービスの概要とRtORBの実装の話に移ります。
CORBAのネーミングサービス(CosNaming)
ネーミンググラフ
CORBAのネーミングサービスは、名前とオブジェクトの参照(CORBAオブジェクトの取得を参照してください)との対応付けを行っています。ネーミングサービスを提供するネームサーバー内では、単純なテーブルでこれを管理しても良いですが、同じ名前が使えなくなりますので、ネーミングコンテキストよ呼ばれる構造が定義されています。このネーミングコンテキストというのは、UNIXファイルシステムのディレクトリ、Windowsのフォルダみたいなもので、階層構造をつくることができます。この階層構造を表したものをネーミンググラフと言います。
前述したように、ネーミンググラフには、UNIXファイルシステムのディレクトリに相当する''ネーミングコンテキスト''とファイルに相当する''オブジェクト参照''があります。また、上の図で''Root''の部分が最上位のネーミングコンテキストで''RootContext''と呼ばれるもので、ネーミングサービスの起点となるところです。
CORBAのネーミングサービスのCORBAオブジェクトの参照を取得すると、この''RootContext''が返されます。そのため、自分の捜しているCOBRAオブジェクトは、このRootContextからの見え方で指定することになります。このやり方は、UNIXで絶対Pathでファイルを指定するやり方とよく似ています。
UNIXのファイルシステムと違うのは、親のネーミングコンテキストを指定する方法がでデフォルトでは提供されていないということです。そのためにあるネーミングコンテキストからの相対的な表現で名前を検索したい場合には、親のネーミングコンテキストを取得するメソッドを自分で実装するしかありません。この機能はあまり頻繁には使いませんので、なくてもあまり問題になりません。
CosNamingのインターフェース
CORBAのネーミングサービスは、CORBAの仕様書の中でIDLで表現されています。このIDLにしたがって、CORBAのネーミングサービスがCORBAライブラリごとに提供されています。
CORBAネーミングサービスでは、登録されたオブジェクト参照やネーミングコンテキストを表現するのにBindingという構造体が定義されており、下記のようになっています。
typedef string Istring; struct NameComponent { Istring id; Istring kind; }; typedef sequence<NameComponent> Name; enum BindingType {nobject, ncontext}; struct Binding { Name binding_name; BindingType binding_type; };
これからも分かるように、ネーミングコンテキストもオブジェクト参照もCORBAネームサーバーの中では、Bindingという構造体で表現されています。このBindingとオブジェクト参照とのテーブルを作成して管理しています。また、PathにあたるものがNameであり、NameはNameComponentの配列になっています。ここで気がつくのは、NameComponentが2つの文字列のペアになっているということです。これは、同じネーミングコンテキストの直下にあってもidとkindどちらかが異なっていれば、別物として扱えることを意味しています。
また、ネーミングコンテキストは、NamingContext というインターフェースが定義されており、下記のようになっています。
interface NamingContext { enum NotFoundReason {missing_node, not_context, not_object}; exception NotFound { NotFoundReason why; Name rest_of_name; }; exception CannotProceed { NamingContext cxt; Name rest_of_name; }; exception InvalidName {}; exception AlreadyBound {}; exception NotEmpty {}; boolean __is_a (in string id); void bind (in Name n, in Object obj) raises (NotFound, CannotProceed, InvalidName, AlreadyBound); void rebind (in Name n, in Object obj) raises (NotFound, CannotProceed, InvalidName); void bind_context (in Name n, in NamingContext nc) raises (NotFound, CannotProceed, InvalidName, AlreadyBound); void rebind_context (in Name n, in NamingContext nc) raises (NotFound, CannotProceed, InvalidName); Object resolve (in Name n) raises (NotFound, CannotProceed, InvalidName); void unbind (in Name n) raises (NotFound, CannotProceed, InvalidName); NamingContext new_context (); NamingContext bind_new_context (in Name n) raises (NotFound, CannotProceed, InvalidName, AlreadyBound); void destroy () raises (NotEmpty); void list (in unsigned long how_many, out BindingList bl, out BindingIterator bi);
上記から分かるように、NamigContextには、下記のメソッドが定義されています。
メソッド | 機能 |
bind | オブジェクト参照を指定されたバインディング名でネーミングサービスに登録。既に登録済みのものがあれば例外を返す |
rebind | bindと同様にネーミングサービスの登録を行うが、既に登録済みのものがあれば上書きする |
bind_context | 指定されたネーミングコンテキストを指定されたバインディング名でネーミングサービスに登録。既に登録済みのものがあれば例外を返す |
rebind_context | bind_contextと同様にネーミングサービスの登録を行うが、既に登録済みのものがあれば上書きする |
resolve | 指定されたバインディング名に関係づけられたオブジェクト参照を獲得する。 |
unbind | 指定されたバインディング名の登録を削除する |
new_context | 新規にネーミングコンテキストを生成する |
bind_new_context | 新規にネーミングコンテキストを生成し、ネーミングサービスの登録。既に登録済みのものがあれば例外を返す |
destroy | ネーミングコンテキストを削除する |
list | ネーミングコンテキストに格納されている、オブジェクト参照のバインディング名リストを獲得する |
上記の表は、基本的なネーミングサービスの機能ですが、これ以外に、BindingIteratorや NamingContextExt(NamingContextの拡張)が定義されています。
OpenRTM-aistでは、ネームサーバーは、omniORBのネームサーバーのようにNamingContextExtが実装されていることを前提にされていましたので、RtORBでもrebindくらいは拡張機能をサポートしています。
RtORBにおけるネーミングサービスの実装状況
RtORBでもネーミングサービスを行うネームサーバーを一応実装しています。「一応」というのは、前述した基本的なインターフェースは、実装していますが、テストが十分にしていませんし、一旦終了するとそれまで覚えいたネーミンググラフをすべて忘れてしまいます。他のネームサーバーとの協調動作までの実装は大変なので行いませんが、登録されたネーミンググラフを定期的に保存し、再構成できるような機能はほしいかなと思います。
RtORBのネームサーバーの動作についての詳細は、別のベージに書いていきたいと思います。