diff --git a/nucleus/device.go b/nucleus/device.go index b111622dfbccbab3b1fe30b584ee7b22d3090762..d155b0c6ab1262a31ab3d8eb5134fdb6dcc73a32 100644 --- a/nucleus/device.go +++ b/nucleus/device.go @@ -110,6 +110,7 @@ func (d *CommonDevice) ProcessResponse(resp proto.Message) error { return d.transport.ProcessResponse(resp, d.GoStruct, d.sbi.Schema()) } +// CsbiDevice is used for the cSBI functionality. type CsbiDevice struct { CommonDevice } @@ -119,22 +120,28 @@ func (d *CsbiDevice) ID() uuid.UUID { return d.UUID } +// Model returns the ygot representation of the Device func (d *CsbiDevice) Model() ygot.GoStruct { return d.GoStruct } +// Transport returns the Transport of the device func (d *CsbiDevice) Transport() transport.Transport { return d.transport } +// Name returns the name of the device func (d *CsbiDevice) Name() string { return d.name } +// SBI returns the sbi of the Device func (d *CsbiDevice) SBI() southbound.SouthboundInterface { return d.sbi } +// ProcessResponse processes a response for the Device func (d *CsbiDevice) ProcessResponse(resp proto.Message) error { + // TODO: callback to send response to caller return d.transport.ProcessResponse(resp, d.GoStruct, d.sbi.Schema()) } diff --git a/nucleus/gnmi_transport.go b/nucleus/gnmi_transport.go index a83ebc585c4e54151c87d9388d06d4f83280db20..0749769d213edc31fe5ee22a10146f5a85de8e92 100644 --- a/nucleus/gnmi_transport.go +++ b/nucleus/gnmi_transport.go @@ -66,12 +66,12 @@ func newGnmiTransport(opts *tpb.TransportOption, sbi southbound.SouthboundInterf "tls": opts.Tls, }).Info("building new gNMI transport") return &Gnmi{ - SetNode: sbi.SetNode(), - RespChan: make(chan *gpb.SubscribeResponse), - Unmarshal: sbi.Unmarshal(), - Options: opts, - client: c, - config: gnmiConfig, + SetNode: sbi.SetNode, + RespChan: make(chan *gpb.SubscribeResponse), + Unmarshal: sbi.Unmarshal, + Options: opts, + client: c, + config: gnmiConfig, }, nil } @@ -227,7 +227,7 @@ func (g *Gnmi) Type() string { // ProcessResponse takes a gNMI response and serializes the contents to the root struct. func (g *Gnmi) ProcessResponse(resp interface{}, root interface{}, s *ytypes.Schema) error { models := s.SchemaTree - d, ok := root.(ygot.ValidatedGoStruct) + d, ok := root.(ygot.ValidatedGoStruct) if !ok { return &errors.ErrInvalidTypeAssertion{} } diff --git a/nucleus/gnmi_transport_test.go b/nucleus/gnmi_transport_test.go index e3d418e741e8d25ff903b15ee856131b82db7a44..cb15e1eea8da2f3d3c483c6f1d74bc6a9b280ad4 100644 --- a/nucleus/gnmi_transport_test.go +++ b/nucleus/gnmi_transport_test.go @@ -257,8 +257,8 @@ func TestGnmi_ProcessResponse(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { g := &Gnmi{ - SetNode: tt.fields.Sbi.SetNode(), - Unmarshal: tt.fields.Sbi.(*OpenConfig).Unmarshal(), + SetNode: tt.fields.Sbi.SetNode, + Unmarshal: tt.fields.Sbi.(*OpenConfig).Unmarshal, } s := tt.fields.Sbi.Schema() resp := gnmiMessages[tt.args.path] diff --git a/nucleus/principalNetworkDomain.go b/nucleus/principalNetworkDomain.go index 670f3b158075f1c02b11dc4c26b57b023108f865..a5b61317957211f195525ab4a6f7745245f4dd24 100644 --- a/nucleus/principalNetworkDomain.go +++ b/nucleus/principalNetworkDomain.go @@ -414,6 +414,7 @@ func (pnd *pndImplementation) handleCsbiEnrolment(name string, opt *tpb.Transpor return nil } +// DeviceDetails contains details of a device used by the cSBI mechanism type DeviceDetails struct { ID string Address string diff --git a/nucleus/southbound.go b/nucleus/southbound.go index ac930032e630cd3f4f5ab920b650d015884393ad..9357da8c30f05977bead1205588864345ddbb1c8 100644 --- a/nucleus/southbound.go +++ b/nucleus/southbound.go @@ -62,21 +62,19 @@ func (oc *OpenConfig) Schema() *ytypes.Schema { // SetNode injects OpenConfig specific model representation to the transport. // Needed for type assertion. -func (oc *OpenConfig) SetNode() func(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error { - return func(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error { - return ytypes.SetNode(schema, root.(*openconfig.Device), path, val, opts...) - } +func (oc *OpenConfig) SetNode(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error { + return ytypes.SetNode(schema, root.(*openconfig.Device), path, val, opts...) } // Unmarshal injects OpenConfig specific model representation to the transport. // Needed for type assertion. -func (oc *OpenConfig) Unmarshal() func([]byte, []string, ygot.ValidatedGoStruct, ...ytypes.UnmarshalOpt) error { - return oc.unmarshal +func (oc *OpenConfig) Unmarshal(bytes []byte, fields []string, goStruct ygot.ValidatedGoStruct, opt ...ytypes.UnmarshalOpt) error { + return unmarshal(oc.Schema(), bytes, fields, goStruct, opt...) } // unmarshal parses gNMI response to a go struct. If it's a root level response // it uses -func (oc *OpenConfig) unmarshal(bytes []byte, fields []string, goStruct ygot.ValidatedGoStruct, opt ...ytypes.UnmarshalOpt) error { +func unmarshal(schema *ytypes.Schema, bytes []byte, fields []string, goStruct ygot.ValidatedGoStruct, opt ...ytypes.UnmarshalOpt) error { defer func() { if r := recover(); r != nil { log.Error(r.(error)) @@ -88,7 +86,7 @@ func (oc *OpenConfig) unmarshal(bytes []byte, fields []string, goStruct ygot.Val var c ygot.ValidatedGoStruct // Load SBI definition - root, err := ygot.DeepCopy(oc.Schema().Root) + root, err := ygot.DeepCopy(schema.Root) if err != nil { return err } @@ -106,10 +104,7 @@ func (oc *OpenConfig) unmarshal(bytes []byte, fields []string, goStruct ygot.Val return err } ygot.PruneEmptyBranches(d) - if err := ygot.MergeStructInto(goStruct, d); err != nil { - return err - } - return nil + return ygot.MergeStructInto(goStruct, d) } // getField traverses the GoStruct and returns the field that represents the @@ -145,26 +140,30 @@ func (oc *OpenConfig) ID() uuid.UUID { // Type returns the Southbound's type func (oc *OpenConfig) Type() spb.Type { return spb.Type_OPENCONFIG } +// Csbi is a stub for the containerised SBI functionality. +// It holds the standard goSDN OPENCONFIG schema for minimum +// compatibility type Csbi struct { schema *ytypes.Schema id uuid.UUID } +// SbiIdentifier returns the identifier as a func (csbi *Csbi) SbiIdentifier() string { return "csbi" } -func (csbi *Csbi) SetNode() func(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error { - return func(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error { - return ytypes.SetNode(schema, root.(*openconfig.Device), path, val, opts...) - } +// SetNode injects schema specific model representation to the transport. +// Needed for type assertion. +func (csbi *Csbi) SetNode(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error { + return ytypes.SetNode(schema, root.(*openconfig.Device), path, val, opts...) } -// Unmarshal injects OpenConfig specific model representation to the transport. +// Unmarshal injects schema specific model representation to the transport. // Needed for type assertion. -func (csbi *Csbi) Unmarshal() func([]byte, []string, ygot.ValidatedGoStruct, ...ytypes.UnmarshalOpt) error { +func (csbi *Csbi) Unmarshal(bytes []byte, fields []string, goStruct ygot.ValidatedGoStruct, opt ...ytypes.UnmarshalOpt) error { oc := OpenConfig{} - return oc.unmarshal + return unmarshal(oc.Schema(), bytes, fields, goStruct, opt...) } // Schema is holding the default OpenConfig schema for minimal compatibility @@ -178,10 +177,12 @@ func (csbi *Csbi) Schema() *ytypes.Schema { return schema } +// ID returns the Southbound's UUID func (csbi *Csbi) ID() uuid.UUID { return csbi.id } +// Type returns the Southbound's type func (csbi *Csbi) Type() spb.Type { return spb.Type_CONTAINERISED } diff --git a/nucleus/southbound_test.go b/nucleus/southbound_test.go index ba26c157c2191b0fc7c5b6e481a2f56e1e2bbc3f..513d84a0a178d1926dcf2266ed17b6c22bbc9399 100644 --- a/nucleus/southbound_test.go +++ b/nucleus/southbound_test.go @@ -170,9 +170,8 @@ func Test_unmarshal(t *testing.T) { } fields := path.ToStrings(resp.Notification[0].Update[0].Path) bytes := resp.Notification[0].Update[0].Val.GetJsonIetfVal() - sbi := NewSBI(spb.Type_OPENCONFIG) - oc := sbi.(*OpenConfig) - if err := oc.unmarshal(bytes, fields, tt.args.goStruct, tt.args.opt...); err != nil { + oc := NewSBI(spb.Type_OPENCONFIG) + if err := unmarshal(oc.Schema(), bytes, fields, tt.args.goStruct, tt.args.opt...); err != nil { if !tt.wantErr { t.Errorf("unmarshal() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/nucleus/store.go b/nucleus/store.go index ea137638a7e59bbd0f335371cd290bf45d56372d..c9706303ae82c9080c6aad5de19a23c17f9b1ff7 100644 --- a/nucleus/store.go +++ b/nucleus/store.go @@ -165,6 +165,8 @@ func (s PndStore) GetPND(id uuid.UUID) (networkdomain.NetworkDomain, error) { return pnd, nil } +// PendingChannels holds channels used communicate with pending +// cSBI deployments func (s PndStore) PendingChannels(id uuid.UUID, parseErrors ...error) (chan DeviceDetails, error) { ch, ok := s.pendingChannels[id] if !ok { @@ -173,10 +175,12 @@ func (s PndStore) PendingChannels(id uuid.UUID, parseErrors ...error) (chan Devi return ch, nil } +// AddPendingChannel adds a pending channel to the map func (s PndStore) AddPendingChannel(id uuid.UUID, ch chan DeviceDetails) { s.pendingChannels[id] = ch } +// RemovePendingChannel removes a pending channel from the map func (s PndStore) RemovePendingChannel(id uuid.UUID) { delete(s.pendingChannels, id) }