diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 10 | ||||
-rw-r--r-- | README.md | 12 | ||||
-rw-r--r-- | api/api.go | 4 | ||||
-rw-r--r-- | api/ifcounters/doc.go | 27 | ||||
-rw-r--r-- | cmd/binapi-generator/doc.go (renamed from binapi_generator/doc.go) | 4 | ||||
-rw-r--r-- | cmd/binapi-generator/generator.go (renamed from binapi_generator/generator.go) | 0 | ||||
-rw-r--r-- | cmd/binapi-generator/generator_test.go (renamed from binapi_generator/generator_test.go) | 0 | ||||
-rw-r--r-- | cmd/binapi-generator/testdata/acl.api.json (renamed from binapi_generator/testdata/acl.api.json) | 0 | ||||
-rw-r--r-- | cmd/binapi-generator/testdata/af_packet.api.json (renamed from binapi_generator/testdata/af_packet.api.json) | 0 | ||||
-rw-r--r-- | cmd/binapi-generator/testdata/input-generate-error.json (renamed from binapi_generator/testdata/input-generate-error.json) | 0 | ||||
-rw-r--r-- | cmd/binapi-generator/testdata/input-read-json-error.json (renamed from binapi_generator/testdata/input-read-json-error.json) | 0 | ||||
-rw-r--r-- | cmd/binapi-generator/testdata/input.txt (renamed from binapi_generator/testdata/input.txt) | 0 | ||||
-rw-r--r-- | cmd/binapi-generator/testdata/ip.api.json (renamed from binapi_generator/testdata/ip.api.json) | 0 | ||||
-rw-r--r-- | core/core.go | 16 | ||||
-rw-r--r-- | core/core_test.go | 14 | ||||
-rw-r--r-- | examples/example_client.go | 17 |
17 files changed, 84 insertions, 22 deletions
@@ -1,3 +1,3 @@ .idea -binapi_generator/binapi_generator +cmd/binapi-generator/binapi-generator examples/examples @@ -1,16 +1,18 @@ 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 ./... @@ -6,7 +6,7 @@ This set of packages provide the API for communication with VPP from Go. It cons - [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 @@ -44,7 +44,7 @@ binary API | +------+ govpp API | 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: @@ -114,22 +114,22 @@ make install ## 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`. @@ -32,7 +32,7 @@ const ( 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 @@ -44,7 +44,7 @@ type Message interface { 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 diff --git a/api/ifcounters/doc.go b/api/ifcounters/doc.go index c918941..35c7f7b 100644 --- a/api/ifcounters/doc.go +++ b/api/ifcounters/doc.go @@ -1,4 +1,29 @@ // 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 diff --git a/binapi_generator/doc.go b/cmd/binapi-generator/doc.go index 84a971b..e8556ec 100644 --- a/binapi_generator/doc.go +++ b/cmd/binapi-generator/doc.go @@ -7,7 +7,7 @@ // 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 diff --git a/binapi_generator/generator.go b/cmd/binapi-generator/generator.go index 22fe3e1..22fe3e1 100644 --- a/binapi_generator/generator.go +++ b/cmd/binapi-generator/generator.go diff --git a/binapi_generator/generator_test.go b/cmd/binapi-generator/generator_test.go index 7527a98..7527a98 100644 --- a/binapi_generator/generator_test.go +++ b/cmd/binapi-generator/generator_test.go diff --git a/binapi_generator/testdata/acl.api.json b/cmd/binapi-generator/testdata/acl.api.json index 91d3d2f..91d3d2f 100644 --- a/binapi_generator/testdata/acl.api.json +++ b/cmd/binapi-generator/testdata/acl.api.json diff --git a/binapi_generator/testdata/af_packet.api.json b/cmd/binapi-generator/testdata/af_packet.api.json index 211fc3e..211fc3e 100644 --- a/binapi_generator/testdata/af_packet.api.json +++ b/cmd/binapi-generator/testdata/af_packet.api.json diff --git a/binapi_generator/testdata/input-generate-error.json b/cmd/binapi-generator/testdata/input-generate-error.json index d5df76e..d5df76e 100644 --- a/binapi_generator/testdata/input-generate-error.json +++ b/cmd/binapi-generator/testdata/input-generate-error.json diff --git a/binapi_generator/testdata/input-read-json-error.json b/cmd/binapi-generator/testdata/input-read-json-error.json index 02691e3..02691e3 100644 --- a/binapi_generator/testdata/input-read-json-error.json +++ b/cmd/binapi-generator/testdata/input-read-json-error.json diff --git a/binapi_generator/testdata/input.txt b/cmd/binapi-generator/testdata/input.txt index e69de29..e69de29 100644 --- a/binapi_generator/testdata/input.txt +++ b/cmd/binapi-generator/testdata/input.txt diff --git a/binapi_generator/testdata/ip.api.json b/cmd/binapi-generator/testdata/ip.api.json index 970ec4b..970ec4b 100644 --- a/binapi_generator/testdata/ip.api.json +++ b/cmd/binapi-generator/testdata/ip.api.json diff --git a/core/core.go b/core/core.go index 550b6a7..5b14a42 100644 --- a/core/core.go +++ b/core/core.go @@ -14,7 +14,7 @@ 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" @@ -40,7 +40,7 @@ type Connection struct { 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 @@ -112,6 +112,9 @@ func Connect(vppAdapter adapter.VppAdapter) (*Connection, error) { // Disconnect disconnects from VPP. func (c *Connection) Disconnect() { + if c == nil { + return + } connLock.Lock() defer connLock.Unlock() @@ -124,12 +127,18 @@ func (c *Connection) Disconnect() { // 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} @@ -311,6 +320,9 @@ func sendReply(ch *api.Channel, reply *api.VppReply) { // 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()) } diff --git a/core/core_test.go b/core/core_test.go index 8bf9311..d3c2e2c 100644 --- a/core/core_test.go +++ b/core/core_test.go @@ -144,6 +144,20 @@ func TestNotifications(t *testing.T) { 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() diff --git a/examples/example_client.go b/examples/example_client.go index 6030469..f2e5804 100644 --- a/examples/example_client.go +++ b/examples/example_client.go @@ -16,7 +16,7 @@ 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" @@ -36,11 +36,20 @@ import ( 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 |