aboutsummaryrefslogtreecommitdiffstats
path: root/proxy/server.go
blob: 20f01f0d3eceb14c6911751f2b7227919f750a39 (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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package proxy

import (
	"fmt"
	"log"
	"reflect"
	"time"

	"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
}

type BinapiCompatibilityRequest struct {
	MsgName string
	Crc     string
}

type BinapiCompatibilityResponse struct {
}

type BinapiTimeoutRequest struct {
	Timeout time.Duration
}

type BinapiTimeoutResponse struct {
}

// 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
}

func (s *BinapiRPC) SetTimeout(req BinapiTimeoutRequest, _ *BinapiTimeoutResponse) error {
	log.Printf("BinapiRPC.SetTimeout - REQ: %#v", req)
	s.binapi.SetReplyTimeout(req.Timeout)
	return nil
}

func (s *BinapiRPC) Compatibility(req BinapiCompatibilityRequest, _ *BinapiCompatibilityResponse) error {
	log.Printf("BinapiRPC.Compatiblity - REQ: %#v", req)
	if val, ok := api.GetRegisteredMessages()[req.MsgName+"_"+req.Crc]; ok {
		return s.binapi.CheckCompatiblity(val)
	}
	return fmt.Errorf("compatibility check failed for the message: %s", req.MsgName+"_"+req.Crc)
}