From c38cb25d746736f062ee16e87f553c8a4ec5fced Mon Sep 17 00:00:00 2001 From: Rastislav Szabo Date: Mon, 22 May 2017 13:59:34 +0200 Subject: [PATCH] binapi-generator renamed & moved, finished documentation Change-Id: I7d3b53fa238e822b36a6a82c61ffb792da3898bf Signed-off-by: Rastislav Szabo --- .gitignore | 2 +- Makefile | 10 ++++---- README.md | 12 +++++----- api/api.go | 4 ++-- api/ifcounters/doc.go | 27 +++++++++++++++++++++- {binapi_generator => cmd/binapi-generator}/doc.go | 4 ++-- .../binapi-generator}/generator.go | 0 .../binapi-generator}/generator_test.go | 0 .../binapi-generator}/testdata/acl.api.json | 0 .../binapi-generator}/testdata/af_packet.api.json | 0 .../testdata/input-generate-error.json | 0 .../testdata/input-read-json-error.json | 0 .../binapi-generator}/testdata/input.txt | 0 .../binapi-generator}/testdata/ip.api.json | 0 core/core.go | 16 +++++++++++-- core/core_test.go | 14 +++++++++++ examples/example_client.go | 17 ++++++++++---- 17 files changed, 84 insertions(+), 22 deletions(-) rename {binapi_generator => cmd/binapi-generator}/doc.go (80%) rename {binapi_generator => cmd/binapi-generator}/generator.go (100%) rename {binapi_generator => cmd/binapi-generator}/generator_test.go (100%) rename {binapi_generator => cmd/binapi-generator}/testdata/acl.api.json (100%) rename {binapi_generator => cmd/binapi-generator}/testdata/af_packet.api.json (100%) rename {binapi_generator => cmd/binapi-generator}/testdata/input-generate-error.json (100%) rename {binapi_generator => cmd/binapi-generator}/testdata/input-read-json-error.json (100%) rename {binapi_generator => cmd/binapi-generator}/testdata/input.txt (100%) rename {binapi_generator => cmd/binapi-generator}/testdata/ip.api.json (100%) diff --git a/.gitignore b/.gitignore index 0f9e2cb..f0ab2aa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ .idea -binapi_generator/binapi_generator +cmd/binapi-generator/binapi-generator examples/examples diff --git a/Makefile b/Makefile index a11ffa4..70f1f45 100644 --- a/Makefile +++ b/Makefile @@ -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 ./... diff --git a/README.md b/README.md index 1d52083..a7d80d9 100644 --- a/README.md +++ b/README.md @@ -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`. diff --git a/api/api.go b/api/api.go index f478bf1..fe6a34a 100644 --- a/api/api.go +++ b/api/api.go @@ -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 similarity index 80% rename from binapi_generator/doc.go rename to 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 similarity index 100% rename from binapi_generator/generator.go rename to cmd/binapi-generator/generator.go diff --git a/binapi_generator/generator_test.go b/cmd/binapi-generator/generator_test.go similarity index 100% rename from binapi_generator/generator_test.go rename to cmd/binapi-generator/generator_test.go diff --git a/binapi_generator/testdata/acl.api.json b/cmd/binapi-generator/testdata/acl.api.json similarity index 100% rename from binapi_generator/testdata/acl.api.json rename to 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 similarity index 100% rename from binapi_generator/testdata/af_packet.api.json rename to 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 similarity index 100% rename from binapi_generator/testdata/input-generate-error.json rename to 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 similarity index 100% rename from binapi_generator/testdata/input-read-json-error.json rename to cmd/binapi-generator/testdata/input-read-json-error.json diff --git a/binapi_generator/testdata/input.txt b/cmd/binapi-generator/testdata/input.txt similarity index 100% rename from binapi_generator/testdata/input.txt rename to cmd/binapi-generator/testdata/input.txt diff --git a/binapi_generator/testdata/ip.api.json b/cmd/binapi-generator/testdata/ip.api.json similarity index 100% rename from binapi_generator/testdata/ip.api.json rename to 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 -- 2.16.6