Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ type Connection interface {
// WatchEvent creates a new watcher for watching events of type specified by
// event parameter. Context can be used to close the watcher.
WatchEvent(ctx context.Context, event Message) (Watcher, error)

// CheckCompatibility checks the compatibility for the given set of messages.
// It will return an error if any of the provided messages are not compatible.
CheckCompatibility(msgs ...Message) error
}

// Watcher provides access to watched event messages. It can be created by calling Connection.WatchEvent.
Expand Down
19 changes: 10 additions & 9 deletions core/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,30 +182,31 @@ func (ch *Channel) newRequest(msg api.Message, multi bool) *vppRequest {
}

func (ch *Channel) CheckCompatiblity(msgs ...api.Message) error {
var comperr api.CompatibilityError
var compErr api.CompatibilityError
for _, msg := range msgs {
_, err := ch.msgIdentifier.GetMessageID(msg)
if err != nil {
if uerr, ok := err.(*adapter.UnknownMsgError); ok {
comperr.IncompatibleMessages = append(comperr.IncompatibleMessages, getMsgID(uerr.MsgName, uerr.MsgCrc))
var uErr *adapter.UnknownMsgError
if errors.As(err, &uErr) {
compErr.IncompatibleMessages = append(compErr.IncompatibleMessages, getMsgID(uErr.MsgName, uErr.MsgCrc))
continue
}
// other errors return immediatelly
// other errors return immediately
return err
}
comperr.CompatibleMessages = append(comperr.CompatibleMessages, getMsgNameWithCrc(msg))
compErr.CompatibleMessages = append(compErr.CompatibleMessages, getMsgNameWithCrc(msg))
}
if len(comperr.IncompatibleMessages) == 0 {
if len(compErr.IncompatibleMessages) == 0 {
return nil
}
if debugOn {
s := ""
for _, msg := range comperr.IncompatibleMessages {
for _, msg := range compErr.IncompatibleMessages {
s += fmt.Sprintf(" - %s\n", msg)
}
ch.logger.Debugf("ERROR: check compatibility: %v:\nIncompatible messages:\n%v", comperr, s)
ch.logger.Debugf("ERROR: check compatibility: %v:\nIncompatible messages:\n%v", compErr, s)
}
return &comperr
return &compErr
}

func (ch *Channel) SubscribeNotification(notifChan chan api.Message, event api.Message) (api.SubscriptionCtx, error) {
Expand Down
9 changes: 9 additions & 0 deletions core/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,15 @@ type Connection struct {
trace *Trace // API tracer (disabled by default)
}

func (c *Connection) CheckCompatibility(msgs ...api.Message) error {
ch, err := c.newAPIChannel(1, 1)
if err != nil {
return fmt.Errorf("unable to do compatibility check: failed to create a new channel: %v", err)
}
defer ch.Close()
return ch.CheckCompatiblity(msgs...)
}

type backgroundLoopStatus int

const (
Expand Down
25 changes: 11 additions & 14 deletions examples/stream-client/stream_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,6 @@ func main() {
log.Fatalln("ERROR: connecting to VPP failed:", e.Error)
}

// check compatibility of used messages
ch, err := conn.NewAPIChannel()
if err != nil {
log.Fatalln("ERROR: creating channel failed:", err)
}
defer ch.Close()
if err := ch.CheckCompatiblity(vpe.AllMessages()...); err != nil {
log.Fatalf("compatibility check failed: %v", err)
}
if err := ch.CheckCompatiblity(interfaces.AllMessages()...); err != nil {
log.Printf("compatibility check failed: %v", err)
}

// process errors encountered during the example
defer func() {
if len(errors) > 0 {
Expand All @@ -84,20 +71,30 @@ func main() {
}
}()

// send and receive messages using stream (low-low level API)
// check the compatibility of used messages
if err = conn.CheckCompatibility(vpe.AllMessages()...); err != nil {
log.Fatalf("compatibility check failed: %v", err)
}
if err = conn.CheckCompatibility(interfaces.AllMessages()...); err != nil {
log.Printf("compatibility check failed: %v", err)
}

// initialize a new stream object
stream, err := conn.NewStream(context.Background(),
core.WithRequestSize(50),
core.WithReplySize(50),
core.WithReplyTimeout(2*time.Second))
if err != nil {
panic(err)
}

defer func() {
if err := stream.Close(); err != nil {
logError(err, "closing the stream")
}
}()

// send and receive messages using stream (low-level API)
getVppVersion(stream)
idx := createLoopback(stream)
interfaceDump(stream)
Expand Down