システムのネットワークトポロジーを俯瞰的に定義しておき、各コンポーネントが自分ノードを指定することで、間接的に接続情報を指定する。
ネットワークトポロジーを有向グラフで表す。エッジの向きは connect 側から accept 側への方向とする。
GraphMLのサブセットを用いてネットワークを定義する方法を提供している。
ここで簡単に GraphML の書き方を説明する。
<?xml version='1.0' encoding='utf-8'?>
<graphml>
<graph>
<node id='node1'>
<port name='port1'><desc>192.168.1.16:10000</desc></port>
</node>
<node id='node2'/>
<edge source='node2' target='node1' targetport='port1'/>
</graph>
</graphml>
これは node2 から node1 へのリンクした単純なトポロジーを表現している。
GraphML は XML であり、ルートエレメントは graphml である。graphml の内部に graph 要素を置き、ここでグラフを定義する。
グラフ定義はノード定義とエッジ定義から構成される。ノードは nine システムの各コンポーネントを示し、エッジはノード間の接続を表す。
node2 のノード定義は単純である。
<node id='node2'/>
node1 の定義は少し複雑になっている。
<node id='node1'>
<port name='port1'><desc>192.168.1.16:10000</desc></port>
</node>
子要素として port が定義されている。GraphML ではノードへの接続ポイントを表すのために使い、nine システムではノードの bind/listen を表すのに用いている。
port の子要素の desc で、bind/listen するアドレスを指定している。GraphML では本来は port の説明を記述する要素であるが、アドレスを簡単に書くために少し目的と外れた使い方をしている。
エッジでは、node2 から node1 へのリンクを定義している。
<edge source='node2' target='node1' targetport='port1'/>
source が connect するノードで、target は connect 先となるノードである。targetport には target ノードで bind/listen している port を指定する。
sample/simple_system/graphml.cpp では、上記の GraphML を用いた接続指定を行っている。
const char* xml =
"<?xml version='1.0' encoding='utf-8'?>"
"<graphml>"
"<graph>"
"<node id='node1'>"
"<port name='port1'><desc>192.168.1.16:10000</desc></port>"
"</node>"
"<node id='node2'/>"
"<edge source='node2' target='node1' targetport='port1'/>"
"</graph>"
"</graphml>";
bool config1(nine::system::SystemServer& sv)
{
nine::system::GraphML* p = nine::system::GraphML::ParseXml(xml);
nine::system::LinkInfo* pLink = p->parse("node1");
bool r = sv.initialize(pLink);
delete pLink;
return r;
}
config1() の最初の行で GraphML インスタンスを生成している。 引数の xml は少し上で定義されている文字列定数で、中身は前に見た GraphML ドキュメントである。
次に、この GraphML オブジェクトの parse() 関数を呼んで、LinkInfo オブジェクトを生成している。parse() には自分のノード名を渡している。この名前は GraphML ドキュメントのノードID と同一である必要がある。
後は生成した LinkInfo を用いて Server を初期化した後で、LinkInfo を delete する。 これで node1 の接続設定が完了する。
config2 は config1 のすぐ下に書かれている。
bool config2(nine::system::SystemServer& sv)
{
nine::system::GraphML* p = nine::system::GraphML::ParseXml(xml);
nine::system::LinkInfo* pLink = p->parse("node2");
pLink->format(std::cout);
bool r = sv.initialize(pLink);
delete pLink;
return r;
}
GraphML::parse() へ渡す自ノードの名前以外は、config1() と全く同じになっている。
単一のネットワーク定義をそれぞれのノードで共有でき、接続設定の管理が簡単になっている。