diff --git a/nucleus/gnmi_transport.go b/nucleus/gnmi_transport.go index db62856e7b8e9759add7e0e66a08cb51b1fcaba1..a83ebc585c4e54151c87d9388d06d4f83280db20 100644 --- a/nucleus/gnmi_transport.go +++ b/nucleus/gnmi_transport.go @@ -3,7 +3,6 @@ package nucleus import ( "context" "reflect" - "strings" "code.fbi.h-da.de/cocsn/gosdn/interfaces/southbound" @@ -242,21 +241,6 @@ func (g *Gnmi) ProcessResponse(resp interface{}, root interface{}, s *ytypes.Sch path := update.Path val, ok := update.Val.Value.(*gpb.TypedValue_JsonVal) if ok { - buf := strings.Builder{} - for _,e := range path.Elem { - key := strings.Title(e.Name) - buf.WriteString(key) - buf.WriteString("_") - } - filter := buf.String() - filter = strings.TrimSuffix(filter,"_") - keys := make([]string, 0) - for k := range models { - if strings.Contains(k, filter) { - keys = append(keys, k) - } - } - //TODO: Fetch field by name opts := []ytypes.UnmarshalOpt{&ytypes.IgnoreExtraFields{}} return g.Unmarshal(val.JsonVal, pathutils.ToStrings(path), d, opts...) } diff --git a/nucleus/southbound.go b/nucleus/southbound.go index ee09868b2bf70e020bcf175a6782e726a91f07df..e46a932357260cd96f32195024e9f57842341243 100644 --- a/nucleus/southbound.go +++ b/nucleus/southbound.go @@ -1,6 +1,7 @@ package nucleus import ( + "code.fbi.h-da.de/cocsn/gosdn/nucleus/errors" "reflect" spb "code.fbi.h-da.de/cocsn/api/go/gosdn/southbound" @@ -67,11 +68,12 @@ func (oc *OpenConfig) SetNode() func(schema *yang.Entry, root interface{}, path // 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 unmarshal + return oc.unmarshal } -// unmarshal parses a root or 1st level gNMI response to a go struct -func unmarshal(bytes []byte, fields []string, goStruct ygot.ValidatedGoStruct, opt ...ytypes.UnmarshalOpt) error { +// 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 { defer func() { if r := recover(); r != nil { log.Error(r.(error)) @@ -85,22 +87,29 @@ func unmarshal(bytes []byte, fields []string, goStruct ygot.ValidatedGoStruct, o var c ygot.ValidatedGoStruct // Load SBI definition - d := openconfig.Device{} - ygot.BuildEmptyTree(&d) - c = getField(&d, fields) + root, err := ygot.DeepCopy(oc.schema.Root) + if err != nil { + return err + } + d, ok := root.(ygot.ValidatedGoStruct) + if !ok { + return &errors.ErrInvalidTypeAssertion{} + } + ygot.BuildEmptyTree(d) + c = getField(d, fields) if err := openconfig.Unmarshal(bytes, c, opt...); err != nil { return err } - if err := ygot.MergeStructInto(goStruct, &d); err != nil { + ygot.PruneEmptyBranches(d) + if err := ygot.MergeStructInto(goStruct, d); err != nil { return err } return nil } -// iter walks down the provided paths and initializes the ygot.GoStruct. It only works for -// the root level. -// TODO(mk): Fix deeper layers +// getField traverses the GoStruct and returns the field that represents the +// tail of the path func getField(inStruct ygot.ValidatedGoStruct, fields []string) ygot.ValidatedGoStruct { defer func() { if r := recover(); r != nil { @@ -145,7 +154,8 @@ func (csbi *Csbi) SetNode() func(schema *yang.Entry, root interface{}, path *gpb // Unmarshal injects OpenConfig specific model representation to the transport. // Needed for type assertion. func (csbi *Csbi) Unmarshal() func([]byte, []string, ygot.ValidatedGoStruct, ...ytypes.UnmarshalOpt) error { - return unmarshal + oc := OpenConfig{} + return oc.unmarshal } // Schema is holding the default OpenConfig schema for minimal compatibility