aboutsummaryrefslogtreecommitdiffstats
path: root/proxy/client.go
diff options
context:
space:
mode:
Diffstat (limited to 'proxy/client.go')
-rw-r--r--proxy/client.go178
1 files changed, 178 insertions, 0 deletions
diff --git a/proxy/client.go b/proxy/client.go
new file mode 100644
index 0000000..72ee9e9
--- /dev/null
+++ b/proxy/client.go
@@ -0,0 +1,178 @@
+package proxy
+
+import (
+ "fmt"
+ "log"
+ "net/rpc"
+ "reflect"
+ "time"
+
+ "git.fd.io/govpp.git/api"
+)
+
+type Client struct {
+ serverAddr string
+ rpc *rpc.Client
+}
+
+// Connect dials remote proxy server on given address and
+// returns new client if successful.
+func Connect(addr string) (*Client, error) {
+ client, err := rpc.DialHTTP("tcp", addr)
+ if err != nil {
+ log.Fatal("Connection error: ", err)
+ }
+ c := &Client{
+ serverAddr: addr,
+ rpc: client,
+ }
+ return c, nil
+}
+
+// NewStatsClient returns new StatsClient which implements api.StatsProvider.
+func (c *Client) NewStatsClient() (*StatsClient, error) {
+ stats := &StatsClient{
+ rpc: c.rpc,
+ }
+ return stats, nil
+}
+
+// NewBinapiClient returns new BinapiClient which implements api.Channel.
+func (c *Client) NewBinapiClient() (*BinapiClient, error) {
+ binapi := &BinapiClient{
+ rpc: c.rpc,
+ }
+ return binapi, nil
+}
+
+type StatsClient struct {
+ rpc *rpc.Client
+}
+
+func (s *StatsClient) GetSystemStats(sysStats *api.SystemStats) error {
+ req := StatsRequest{StatsType: "system"}
+ resp := StatsResponse{SysStats: sysStats}
+ return s.rpc.Call("StatsRPC.GetStats", req, &resp)
+}
+
+func (s *StatsClient) GetNodeStats(nodeStats *api.NodeStats) error {
+ req := StatsRequest{StatsType: "node"}
+ resp := StatsResponse{NodeStats: nodeStats}
+ return s.rpc.Call("StatsRPC.GetStats", req, &resp)
+}
+
+func (s *StatsClient) GetInterfaceStats(ifaceStats *api.InterfaceStats) error {
+ req := StatsRequest{StatsType: "interface"}
+ resp := StatsResponse{IfaceStats: ifaceStats}
+ return s.rpc.Call("StatsRPC.GetStats", req, &resp)
+}
+
+func (s *StatsClient) GetErrorStats(errStats *api.ErrorStats) error {
+ req := StatsRequest{StatsType: "error"}
+ resp := StatsResponse{ErrStats: errStats}
+ return s.rpc.Call("StatsRPC.GetStats", req, &resp)
+}
+
+func (s *StatsClient) GetBufferStats(bufStats *api.BufferStats) error {
+ req := StatsRequest{StatsType: "buffer"}
+ resp := StatsResponse{BufStats: bufStats}
+ return s.rpc.Call("StatsRPC.GetStats", req, &resp)
+}
+
+type BinapiClient struct {
+ rpc *rpc.Client
+}
+
+func (b *BinapiClient) SendRequest(msg api.Message) api.RequestCtx {
+ req := &requestCtx{
+ rpc: b.rpc,
+ req: msg,
+ }
+ log.Printf("SendRequest: %T %+v", msg, msg)
+ return req
+}
+
+type requestCtx struct {
+ rpc *rpc.Client
+ req api.Message
+}
+
+func (r *requestCtx) ReceiveReply(msg api.Message) error {
+ req := BinapiRequest{
+ Msg: r.req,
+ ReplyMsg: msg,
+ }
+ resp := BinapiResponse{}
+
+ err := r.rpc.Call("BinapiRPC.Invoke", req, &resp)
+ if err != nil {
+ return fmt.Errorf("RPC call failed: %v", err)
+ }
+
+ // we set the value of msg to the value from response
+ reflect.ValueOf(msg).Elem().Set(reflect.ValueOf(resp.Msg).Elem())
+
+ return nil
+}
+
+func (b *BinapiClient) SendMultiRequest(msg api.Message) api.MultiRequestCtx {
+ req := &multiRequestCtx{
+ rpc: b.rpc,
+ req: msg,
+ }
+ log.Printf("SendMultiRequest: %T %+v", msg, msg)
+ return req
+}
+
+type multiRequestCtx struct {
+ rpc *rpc.Client
+ req api.Message
+
+ index int
+ replies []api.Message
+}
+
+func (r *multiRequestCtx) ReceiveReply(msg api.Message) (stop bool, err error) {
+ // we call Invoke only on first ReceiveReply
+ if r.index == 0 {
+ req := BinapiRequest{
+ Msg: r.req,
+ ReplyMsg: msg,
+ IsMulti: true,
+ }
+ resp := BinapiResponse{}
+
+ err := r.rpc.Call("BinapiRPC.Invoke", req, &resp)
+ if err != nil {
+ return false, fmt.Errorf("RPC call failed: %v", err)
+ }
+
+ r.replies = resp.Msgs
+ }
+
+ if r.index >= len(r.replies) {
+ return true, nil
+ }
+
+ // we set the value of msg to the value from response
+ reflect.ValueOf(msg).Elem().Set(reflect.ValueOf(r.replies[r.index]).Elem())
+ r.index++
+
+ return false, nil
+}
+
+func (b *BinapiClient) SubscribeNotification(notifChan chan api.Message, event api.Message) (api.SubscriptionCtx, error) {
+ panic("implement me")
+}
+
+func (b *BinapiClient) SetReplyTimeout(timeout time.Duration) {
+ panic("implement me")
+}
+
+func (b *BinapiClient) CheckCompatiblity(msgs ...api.Message) error {
+ return nil // TODO: proxy this
+}
+
+func (b *BinapiClient) Close() {
+ b.rpc.Close()
+}