遺跡の魂を直接読み解け ~RestSharpで、Redfishの深淵を覗く~
旅の途中、興味深いオアシスを見つけた。忘れないうちに、この羊皮紙に記しておくとしよう。
前回の旅で、我々はRedfishのモックアップという名の「地図」から、その構造を読み解く魔法を編み出した。しかし、地図はあくまで地図。真の冒険者ならば、本物の遺跡(サーバ)へ赴き、その魂に直接触れたいと思うのが常だろう。
今回は、前回の魔法をさらに進化させ、RestSharpという名の翼を授ける。これにより、我々はファイルという名の書庫から飛び立ち、ネットワークという広大な空を経て、サーバ(BMC)という名の神殿に直接アクセスするのだ。自己署名証明書という結界を突破し、@odata.idという糸を辿って、遺跡の魂の全てを一枚の羊皮紙にマージする。さあ、真の探査の旅が始まる。
この羊皮紙のあらまし
この羊皮紙が導く者
- サーバ(BMC)という名の神殿から、Redfishの情報を一気に引き出したいと願う者
- RestSharpという翼を使い、REST APIという大空を自在に飛び回りたい探求者
翼を授ける儀式:RestSharpとの契約
今回の旅の鍵を握るのは、HTTPアクセスを驚くほど簡単にする魔法の道具「RestSharp」だ。
Hello from RestSharp | RestSharp
この翼を使いこなす作法は、極めてシンプルだ。
RestClientという翼を広げる。この時、自己署名証明書という名の結界を無視するため、RemoteCertificateValidationCallbackで「全てを信じる」と誓いを立てる。RestRequestで行き先(URI)を定め、ExecuteAsyncの呪文で大空へ飛び立つ。- 戻ってきた
RestResponseという名の伝書バトから、お目当ての情報を受け取る。
秘儀の全貌:魂をマージする呪文
この秘儀の核心は、遺跡の魂(JSON)を読み解き、繋ぎ合わせるための、二つの設計図(クラス)と、それらを操る「再帰の魔法(Readメソッド)」にある。
設計図その1:JsonElement
これは、遺跡から得られる魂の欠片、一つ一つの情報を記録するための、最小単位の器だ。
/// <summary> /// JSONの要素 /// </summary> class JsonElement { public JsonToken TokenType { get; set; } public object? Value { get; set; } }
設計図その2:Redfish
そしてこれが、旅の全てを司る、我々の分身だ。翼(RestClient)を持ち、魂の欠片(JsonElement)を集め、そして再帰の魔法を唱える。
/// <summary> /// Redfishマージ用 /// </summary> class Redfish { public RestClient? Client { get; set; } public List<JsonElement> Elements { get; set; } = new List<JsonElement>(); HashSet<JsonToken> JsonTags { get; } = new HashSet<JsonToken>() { JsonToken.StartObject, JsonToken.EndObject, JsonToken.StartArray, JsonToken.EndArray }; HashSet<string> OdataItems { get; set; } = new HashSet<string>() { "/redfish/v1/" }; /// <summary> /// 全ての魂を再帰的に読み込む /// </summary> public void Read(string path) { if (Client == null) return; // RestSharpの翼で、遺跡へ直接問いかける var request = new RestRequest(path); request.AddHeader("Content-Type", "application/json"); var response = Client.ExecuteAsync(request, Method.Get).Result; if (response == null || response.Content == null || response.ResponseUri == null) return; Console.WriteLine($"{response.ResponseUri.AbsoluteUri}\n{response.Content}\n"); // 遺跡からの応答(JSON)を解読し、 // 新たな「@odata.id」という名の道を見つけたら、 // 再びこのReadメソッド自身を呼び出し、旅を続ける(再帰) var reader = new JsonTextReader(new StringReader(response.Content)); while (reader.Read()) { var val1 = reader.Value; Elements.Add(new JsonElement() { TokenType = reader.TokenType, Value = val1 }); if (reader.TokenType != JsonToken.PropertyName) continue; reader.Read(); var val2 = reader.Value; Elements.Add(new JsonElement() { TokenType = reader.TokenType, Value = val2 }); if (val1 == null || val2 == null) continue; if (JsonTags.Contains(reader.TokenType)) continue; if (!((string)val1).Equals("@odata.id")) continue; if (!OdataItems.Contains((string)val2)) { OdataItems.Add((string)val2); Elements.Add(new JsonElement() { TokenType = JsonToken.PropertyName, Value = "/* @odata.child */" }); Read((string)val2); } } } // ...(Writeメソッドは、集めたElementsをファイルに書き出すだけなので省略)... }
この再帰の魔法により、最初に/redfish/v1/という入口から入るだけで、そこから繋がる全ての道を自動的に探査し、巨大な一枚の地図(JSONファイル)として描き出すことができるのだ。
羊皮紙を巻く前に
この進化版の魔法を使い、私はいくつかの本物の遺跡(サーバ)を探査してみた。中には、100MBを超えるほどの膨大な魂を持つ遺跡もあり、道半ばで力尽きることもあった。ここに掲載した呪文は、あくまで秘儀の骨子。実戦で使うには、エラー処理やリトライ処理という名の、さらなる鎧を纏わせる必要があるだろう。
しかし、これでついに、Redfishという広大な遺跡の、完全な地図を描き出すための基礎は、全て整った。 いずれ、この魔法を核として、誰もが直感的に遺跡を探査できる、GUI版の魔法の眼鏡(Redfishビューワ)を創り出してみたいものだ。
おっと、どうやら相棒が腹を空かせたようだ。今日はこのへんで筆を置くとしよう。
砂漠で見つけた魔法のランプ
- 前回の冒険の記録(ファイル読み込み編)
- RestSharp 公式の古文書
ラクダの独り言
ご主人が、羊皮紙を読むだけじゃ飽き足らず、今度は「れすとしょーぷ」とかいう、鳥の翼みたいなもので、遠くの神殿から直接情報を引っこ抜いてきている。便利かもしれんが、そんなことばっかりしてると、自分の足で歩くことを忘れちまうんじゃないのかね。まったく、横着なんだから。おっと、喉が渇いてきやがった。