aboutsummaryrefslogtreecommitdiffstats
path: root/proxy/server.go
blob: df623562b923965542c562611e91d00ea730f500 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package proxy

import (
	"fmt"
	"log"
	"reflect"

	"git.fd.io/govpp.git/api"
)

type StatsRequest struct {
	StatsType string
}

type StatsResponse struct {
	SysStats   *api.SystemStats
	NodeStats  *api.NodeStats
	IfaceStats *api.InterfaceStats
	ErrStats   *api.ErrorStats
	BufStats   *api.BufferStats
}

// StatsRPC is a RPC server for proxying client request to api.StatsProvider.
type StatsRPC struct {
	stats api.StatsProvider
}

// NewStatsRPC returns new StatsRPC to be used as RPC server
// proxying request to given api.StatsProvider.
func NewStatsRPC(stats api.StatsProvider) *StatsRPC {
	return &StatsRPC{stats: stats}
}

func (s *StatsRPC) GetStats(req StatsRequest, resp *StatsResponse) error {
	log.Printf("StatsRPC.GetStats - REQ: %+v", req)

	switch req.StatsType {
	case "system":
		resp.SysStats = new(api.SystemStats)
		return s.stats.GetSystemStats(resp.SysStats)
	case "node":
		resp.NodeStats = new(api.NodeStats)
		return s.stats.GetNodeStats(resp.NodeStats)
	case "interface":
		resp.IfaceStats = new(api.InterfaceStats)
		return s.stats.GetInterfaceStats(resp.IfaceStats)
	case "error":
		resp.ErrStats = new(api.ErrorStats)
		return s.stats.GetErrorStats(resp.ErrStats)
	case "buffer":
		resp.BufStats = new(api.BufferStats)
		return s.stats.GetBufferStats(resp.BufStats)
	default:
		return fmt.Errorf("unknown stats type: %s", req.StatsType)
	}
}

type BinapiRequest struct {
	Msg      api.Message
	IsMulti  bool
	ReplyMsg api.Message
}

type BinapiResponse struct {
	Msg  api.Message
	Msgs []api.Message
}

// BinapiRPC is a RPC server for proxying client request to api.Channel.
type BinapiRPC struct {
	binapi api.Channel
}

// NewBinapiRPC returns new BinapiRPC to be used as RPC server
// proxying request to given api.Channel.
func NewBinapiRPC(binapi api.Channel) *BinapiRPC {
	return &BinapiRPC{binapi: binapi}
}

func (s *BinapiRPC) Invoke(req BinapiRequest, resp *BinapiResponse) error {
	log.Printf("BinapiRPC.Invoke - REQ: %#v", req)

	if req.IsMulti {
		multi := s.binapi.SendMultiRequest(req.Msg)
		for {
			// create new message in response of type ReplyMsg
			msg := reflect.New(reflect.TypeOf(req.ReplyMsg).Elem()).Interface().(api.Message)

			stop, err := multi.ReceiveReply(msg)
			if err != nil {
				return err
			} else if stop {
				break
			}

			resp.Msgs = append(resp.Msgs, msg)
		}
	} else {
		// create new message in response of type ReplyMsg
		resp.Msg = reflect.New(reflect.TypeOf(req.ReplyMsg).Elem()).Interface().(api.Message)

		err := s.binapi.SendRequest(req.Msg).ReceiveReply(resp.Msg)
		if err != nil {
			return err
		}
	}

	return nil
}