+// Copyright (c) 2019 Cisco and/or its affiliates.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
package proxy
import (
"fmt"
- "log"
"net/rpc"
"reflect"
"time"
"git.fd.io/govpp.git/api"
+ "git.fd.io/govpp.git/core"
)
type Client struct {
func Connect(addr string) (*Client, error) {
client, err := rpc.DialHTTP("tcp", addr)
if err != nil {
- log.Fatal("Connection error: ", err)
+ return nil, fmt.Errorf("connection error:%v", err)
}
c := &Client{
serverAddr: addr,
// NewBinapiClient returns new BinapiClient which implements api.Channel.
func (c *Client) NewBinapiClient() (*BinapiClient, error) {
binapi := &BinapiClient{
- rpc: c.rpc,
+ rpc: c.rpc,
+ timeout: core.DefaultReplyTimeout,
}
return binapi, nil
}
}
func (s *StatsClient) GetSystemStats(sysStats *api.SystemStats) error {
+ // we need to start with a clean, zeroed item before decoding
+ // 'cause if the new values are 'zero' for the type, they will be ignored
+ // by the decoder. (i.e the old values will be left unchanged).
req := StatsRequest{StatsType: "system"}
- resp := StatsResponse{SysStats: sysStats}
- return s.rpc.Call("StatsRPC.GetStats", req, &resp)
+ resp := StatsResponse{SysStats: new(api.SystemStats)}
+ if err := s.rpc.Call("StatsRPC.GetStats", req, &resp); err != nil {
+ return err
+ }
+ *sysStats = *resp.SysStats
+ return nil
}
func (s *StatsClient) GetNodeStats(nodeStats *api.NodeStats) error {
req := StatsRequest{StatsType: "node"}
- resp := StatsResponse{NodeStats: nodeStats}
- return s.rpc.Call("StatsRPC.GetStats", req, &resp)
+ resp := StatsResponse{NodeStats: new(api.NodeStats)}
+ if err := s.rpc.Call("StatsRPC.GetStats", req, &resp); err != nil {
+ return err
+ }
+ *nodeStats = *resp.NodeStats
+ return nil
}
func (s *StatsClient) GetInterfaceStats(ifaceStats *api.InterfaceStats) error {
req := StatsRequest{StatsType: "interface"}
- resp := StatsResponse{IfaceStats: ifaceStats}
- return s.rpc.Call("StatsRPC.GetStats", req, &resp)
+ resp := StatsResponse{IfaceStats: new(api.InterfaceStats)}
+ if err := s.rpc.Call("StatsRPC.GetStats", req, &resp); err != nil {
+ return err
+ }
+ *ifaceStats = *resp.IfaceStats
+ return nil
}
func (s *StatsClient) GetErrorStats(errStats *api.ErrorStats) error {
req := StatsRequest{StatsType: "error"}
- resp := StatsResponse{ErrStats: errStats}
- return s.rpc.Call("StatsRPC.GetStats", req, &resp)
+ resp := StatsResponse{ErrStats: new(api.ErrorStats)}
+ if err := s.rpc.Call("StatsRPC.GetStats", req, &resp); err != nil {
+ return err
+ }
+ *errStats = *resp.ErrStats
+ return nil
}
func (s *StatsClient) GetBufferStats(bufStats *api.BufferStats) error {
req := StatsRequest{StatsType: "buffer"}
- resp := StatsResponse{BufStats: bufStats}
- return s.rpc.Call("StatsRPC.GetStats", req, &resp)
+ resp := StatsResponse{BufStats: new(api.BufferStats)}
+ if err := s.rpc.Call("StatsRPC.GetStats", req, &resp); err != nil {
+ return err
+ }
+ *bufStats = *resp.BufStats
+ return nil
}
type BinapiClient struct {
- rpc *rpc.Client
+ rpc *rpc.Client
+ timeout time.Duration
}
func (b *BinapiClient) SendRequest(msg api.Message) api.RequestCtx {
req := &requestCtx{
- rpc: b.rpc,
- req: msg,
+ rpc: b.rpc,
+ timeout: b.timeout,
+ req: msg,
}
- log.Printf("SendRequest: %T %+v", msg, msg)
+ log.Debugf("SendRequest: %T %+v", msg, msg)
return req
}
type requestCtx struct {
- rpc *rpc.Client
- req api.Message
+ rpc *rpc.Client
+ req api.Message
+ timeout time.Duration
}
func (r *requestCtx) ReceiveReply(msg api.Message) error {
req := BinapiRequest{
Msg: r.req,
ReplyMsg: msg,
+ Timeout: r.timeout,
}
resp := BinapiResponse{}
func (b *BinapiClient) SendMultiRequest(msg api.Message) api.MultiRequestCtx {
req := &multiRequestCtx{
- rpc: b.rpc,
- req: msg,
+ rpc: b.rpc,
+ timeout: b.timeout,
+ req: msg,
}
- log.Printf("SendMultiRequest: %T %+v", msg, msg)
+ log.Debugf("SendMultiRequest: %T %+v", msg, msg)
return req
}
type multiRequestCtx struct {
- rpc *rpc.Client
- req api.Message
+ rpc *rpc.Client
+ req api.Message
+ timeout time.Duration
index int
replies []api.Message
Msg: r.req,
ReplyMsg: msg,
IsMulti: true,
+ Timeout: r.timeout,
}
resp := BinapiResponse{}
}
func (b *BinapiClient) SetReplyTimeout(timeout time.Duration) {
- panic("implement me")
+ b.timeout = timeout
}
func (b *BinapiClient) CheckCompatiblity(msgs ...api.Message) error {
- return nil // TODO: proxy this
+ msgNamesCrscs := make([]string, 0, len(msgs))
+
+ for _, msg := range msgs {
+ msgNamesCrscs = append(msgNamesCrscs, msg.GetMessageName()+"_"+msg.GetCrcString())
+ }
+
+ req := BinapiCompatibilityRequest{MsgNameCrcs: msgNamesCrscs}
+ resp := BinapiCompatibilityResponse{}
+
+ if err := b.rpc.Call("BinapiRPC.Compatibility", req, &resp); err != nil {
+ return err
+ }
+
+ return nil
}
func (b *BinapiClient) Close() {