.idea
-binapi_generator/binapi_generator
+cmd/binapi-generator/binapi-generator
examples/examples
build:
- @cd binapi_generator && go build -v
+ @cd cmd/binapi-generator && go build -v
+ @cd examples && go build -v
test:
- @cd binapi_generator && go test -cover .
+ @cd cmd/binapi-generator && go test -cover .
@cd api && go test -cover ./...
@cd core && go test -cover .
install:
- @cd binapi_generator && go install -v
+ @cd cmd/binapi-generator && go install -v
clean:
- @rm binapi_generator/binapi_generator
+ @rm cmd/binapi-generator/binapi-generator
+ @rm examples/examples
generate:
@cd core && go generate ./...
- [api](api/api.go): API for communication with govpp core using Go channels (without the need of importing the govpp core package itself),
- [core](core/): main functionality of the govpp, sends and receives the messages to/from VPP using the adapter, marshalls/unmarshalls them and forwards them between the client Go channels and the VPP,
- [adapter](adapter/): adapter between govpp core and the VPP, responsible for sending and receiving binary-encoded data via shared memory,
-- [binapi_generator](binapi_generator/generator.go): Generator of Go structs out of the VPP binary API definitions in JSON format,
+- [binapi-generator](cmd/binapi-generator/generator.go): Generator of Go structs out of the VPP binary API definitions in JSON format,
- [examples](examples/): example VPP management application that exercises the govpp API on real-world use-cases.
The design with separated govpp API package ([api](api/api.go)) and the govpp core package ([core](core/)) enables
Generating Go bindings from the JSON files located in the `/usr/share/vpp/api/` directory
into the Go packages that will be created inside of the `bin_api` directory:
```
-go run binapi_generator/generator.go --input-dir=/usr/share/vpp/api/ --output-dir=bin_api
+binapi-generator --input-dir=/usr/share/vpp/api/ --output-dir=bin_api
```
Usage of the generated bindings:
## Building Go bindings from VPP binary APIs
-Once you have `binapi_generator` installed in your `$GOPATH`, you can use it to generate Go bindings from
+Once you have `binapi-generator` installed in your `$GOPATH`, you can use it to generate Go bindings from
VPP APis in JSON format. The JSON input can be specified as a single file (`input-file` argument), or
as a directory that will be scanned for all `.json` files (`input-dir`). The generated Go bindings will
be placed into `output-dir` (by default current working directory), where each Go package will be placed into
a separated directory, e.g.:
```
-binapi_generator --input-file=examples/bin_api/acl.api.json --output-dir=examples/bin_api
-binapi_generator --input-dir=examples/bin_api --output-dir=examples/bin_api
+binapi-generator --input-file=examples/bin_api/acl.api.json --output-dir=examples/bin_api
+binapi-generator --input-dir=examples/bin_api --output-dir=examples/bin_api
```
In Go, [go generate](https://blog.golang.org/generate) tool can be leveraged to ease the code generation
process. It allows to specify generator instructions in any one of the regular (non-generated) `.go` files
that are dependent on generated code using special comments, e.g. the one from [example_client](examples/example_client.go):
```go
-// go:generate binapi_generator --input-dir=bin_api --output-dir=bin_api
+// go:generate binapi-generator --input-dir=bin_api --output-dir=bin_api
```
The comment must start at the beginning of the line and have no spaces between the `//` and the `go:generate`.
OtherMessage
)
-// Message is an interface that is implemented by all VPP Binary API messages generated by the binapi_generator.
+// Message is an interface that is implemented by all VPP Binary API messages generated by the binapi-generator.
type Message interface {
// GetMessageName returns the original VPP name of the message, as defined in the VPP API.
GetMessageName() string
GetCrcString() string
}
-// DataType is an interface that is implemented by all VPP Binary API data types by the binapi_generator.
+// DataType is an interface that is implemented by all VPP Binary API data types by the binapi-generator.
type DataType interface {
// GetTypeName returns the original VPP name of the data type, as defined in the VPP API.
GetTypeName() string
// Package ifcounters provides the helper API for decoding VnetInterfaceCounters binary API message
// that contains binary-encoded statistics data into the Go structs that are better consumable by the Go code.
-// TODO: example usage - currently in the example_client.go
+//
+// VPP provides two types of interface counters that can be encoded inside of a single VnetInterfaceCounters
+// message: simple and combined. For both of them, ifcounters API provides a separate decode function:
+// DecodeCounters or DecodeCombinedCounters. The functions return a slice of simple or combined counters respectively:
+//
+// notifMsg := <-notifChan:
+// notif := notifMsg.(*interfaces.VnetInterfaceCounters)
+//
+// if notif.IsCombined == 0 {
+// // simple counter
+// counters, err := ifcounters.DecodeCounters(ifcounters.VnetInterfaceCounters(*notif))
+// if err != nil {
+// fmt.Println("Error:", err)
+// } else {
+// fmt.Printf("%+v\n", counters)
+// }
+// } else {
+// // combined counter
+// counters, err := ifcounters.DecodeCombinedCounters(ifcounters.VnetInterfaceCounters(*notif))
+// if err != nil {
+// fmt.Println("Error:", err)
+// } else {
+// fmt.Printf("%+v\n", counters)
+// }
+// }
+//
package ifcounters
// where each Go package will be placed into its own separate directory,
// for example:
//
-// binapi_generator --input-file=examples/bin_api/acl.api.json --output-dir=examples/bin_api
-// binapi_generator --input-dir=examples/bin_api --output-dir=examples/bin_api
+// binapi-generator --input-file=examples/bin_api/acl.api.json --output-dir=examples/bin_api
+// binapi-generator --input-dir=examples/bin_api --output-dir=examples/bin_api
//
package main
package core
-//go:generate binapi_generator --input-file=/usr/share/vpp/api/vpe.api.json --output-dir=./bin_api
+//go:generate binapi-generator --input-file=/usr/share/vpp/api/vpe.api.json --output-dir=./bin_api
import (
"errors"
vpp adapter.VppAdapter // VPP adapter
codec *MsgCodec // message codec
- msgIDs map[string]uint16 // map os message IDs indexed by message name + CRC
+ msgIDs map[string]uint16 // map of message IDs indexed by message name + CRC
msgIDsLock sync.RWMutex // lock for the message IDs map
channels map[uint32]*api.Channel // map of all API channels indexed by the channel ID
// Disconnect disconnects from VPP.
func (c *Connection) Disconnect() {
+ if c == nil {
+ return
+ }
connLock.Lock()
defer connLock.Unlock()
// NewAPIChannel returns a new API channel for communication with VPP via govpp core.
// It uses default buffer sizes for the request and reply Go channels.
func (c *Connection) NewAPIChannel() (*api.Channel, error) {
+ if c == nil {
+ return nil, errors.New("nil connection passed in")
+ }
return c.NewAPIChannelBuffered(requestChannelBufSize, replyChannelBufSize)
}
// NewAPIChannelBuffered returns a new API channel for communication with VPP via govpp core.
// It allows to specify custom buffer sizes for the request and reply Go channels.
func (c *Connection) NewAPIChannelBuffered(reqChanBufSize, replyChanBufSize int) (*api.Channel, error) {
+ if c == nil {
+ return nil, errors.New("nil connection passed in")
+ }
chID := atomic.AddUint32(&c.maxChannelID, 1)
chMeta := &channelMetadata{id: chID}
// GetMessageID returns message identifier of given API message.
func (c *Connection) GetMessageID(msg api.Message) (uint16, error) {
+ if c == nil {
+ return 0, errors.New("nil connection passed in")
+ }
return c.messageNameToID(msg.GetMessageName(), msg.GetCrcString())
}
Expect(err).ShouldNot(HaveOccurred())
}
+func TestNilConnection(t *testing.T) {
+ var conn *Connection
+
+ ch, err := conn.NewAPIChannel()
+ Expect(ch).Should(BeNil())
+ Expect(err).Should(HaveOccurred())
+ Expect(err.Error()).To(ContainSubstring("nil"))
+
+ ch, err = conn.NewAPIChannelBuffered(1, 1)
+ Expect(ch).Should(BeNil())
+ Expect(err).Should(HaveOccurred())
+ Expect(err.Error()).To(ContainSubstring("nil"))
+}
+
func TestDoubleConnection(t *testing.T) {
ctx := setupTest(t)
defer ctx.teardownTest()
package main
// Generates Go bindings for all VPP APIs located in the json directory.
-//go:generate binapi_generator --input-dir=bin_api --output-dir=bin_api
+//go:generate binapi-generator --input-dir=bin_api --output-dir=bin_api
import (
"fmt"
func main() {
fmt.Println("Starting example VPP client...")
- // connect to VPP and create an API channel that will be used in the examples
- conn, _ := govpp.Connect()
+ // connect to VPP
+ conn, err := govpp.Connect()
+ if err != nil {
+ fmt.Println("Error:", err)
+ os.Exit(1)
+ }
defer conn.Disconnect()
- ch, _ := conn.NewAPIChannel()
+ // create an API channel that will be used in the examples
+ ch, err := conn.NewAPIChannel()
+ if err != nil {
+ fmt.Println("Error:", err)
+ os.Exit(1)
+ }
defer ch.Close()
// check whether the VPP supports our version of some messages