gobgp経由のflowspecこんどはclojureで呼び出せるかやってました。
clojureと銘打ってますが、grpcのコアな部分・protobufとかはjavaライブラリに依存することになります。それゆえ、調べごと・実装のほとんどすべてはjavaと格闘することになりました。
javaのほうでrpc呼び出しのstaticメソッド作って呼んでいるだけなので、はい、すみません今回やった部分で clojure ほとんど関係ありません。ですがclojure を使ってgrpc経由で他のプロセスとつながることできました。*1clojureでブリブリ判断処理やってbgpにメッセージを送る、みたいな用途に使えそうであります。
build gobgp-grpc using java
ここに、gradle かmaven を使うとjavaコードで必要なプラグインを使ってコードが生成されると書いてありまして、自分はmaven使いました。そっちのほうに親しんでいるからです。(うまくいかない場合の対応とかちょっと手抜きですすめたい場合とかになんとかしやすい)*2といいながら、pom.xmlを作るところまでで時間の多くを費やしてしまいました。protoc呼び出しのときプラグイン付きでないとgrpcのsubコードが出力されなく最初インターフェースクラスのコードに全部xxGrpcとか含まれているのかと勘違いし続けてました。
javaのprotobuf部分、python/nodejsとはまた違った雰囲気の書き方でデータ構造のシリアライズ部分書くことになりましたが、今つかんでるコツはこんな感じです。
- データ構造インターフェースのオブジェクトクラスのインスタンスのために、newBuilder()でまずBuilderインスタンスを作る。
- 単パラメータはsetXXX()でBuilderインスタンスに格納する*3
- repeatedパラメータは要素ごとにaddXXX()でBuilderインスタンスに格納する
- Builderインスタンスのbuild()の戻り値をAny.pack()する。
pom.xml(+パラメータ埋め込みで記述してしまっているclientコード例)はここに残しておきます。client例は値も架空の固定値でflowspecだけを考慮した例です。gobgpのデータ構造の扱いとしてもjavaの書き方としても整理の余地ありありです。。。
gobgpの*.protoファイルを原本からsrc/main/protoにコピーしてきて
mvn package
`target/grpc-gobgp-1.0-SNAPSHOT-jar-with-dependencies.jar`に必要jar全部込みで出力されます。今時点、エントリをexample.Client#mainに指定してあります。
run gobgp + flowspec by clojure
nao@hnd:gobgp-grpc-java$ clojure -cp target/grpc-gobgp-1.0-SNAPSHOT-jar-with-dependencies.jar Clojure 1.9.0 user=> (ns user (:import gobgpapi.example.Client)) nil user=> (gobgpapi.example.Client/process "add") call addPath Done nil user=> (gobgpapi.example.Client/process "del") call delPath Done nil user=>
実行前/process "add"後/process "del"後/のgobgpで見れる情報はこんな感じ
nao@hnd:$ #before status nao@hnd:$ gobgp global rib -a ipv4-flowspec Network not in table nao@hnd:$ nao@hnd:$ #after calling (process "add") nao@hnd:$ gobgp global rib -a ipv4-flowspec Network Next Hop AS_PATH Age Attrs *> [destination: 1.2.3.4/32][source: 5.6.7.8/32][protocol: ==udp][port: ==1900 ==11211] fictitious 00:00:03 [{Extcomms: [discard]} {Origin: i}] nao@hnd:$ nao@hnd:$ #after calling (process "del") nao@hnd:$ gobgp global rib -a ipv4-flowspec Network not in table
補足
ubuntu(16/18)の上で、aptでclojureインストールすると起動スクリプトはrlwrapというコマンドでラップされて起動するそうです。*4上記の実行例はaptインストールのclojureによります。ここのインストール方法だと少し動きが変わってしまいます。こっちの起動スクリプトは読み込みjarの指定をdeps.ednというファイルで指定してmavenで引っ張ってこれる仕組みになっています。この仕組みは開発者向け、ということと理解してます。
蛇足
最近、個人で動かすjavaはAmazon/Correttoを使ってます。*5