Skip to content

Commit e738225

Browse files
fix identityref conversion
add more detailed log line todo: validate enums Fix NavigateLeafRef for leaf to leaflist references allow correct parsing of leaf to leaflist leafrefs
1 parent 2aae368 commit e738225

File tree

5 files changed

+43
-24
lines changed

5 files changed

+43
-24
lines changed

pkg/datastore/target/nc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ func (t *ncTarget) Get(ctx context.Context, req *sdcpb.GetDataRequest) (*sdcpb.G
100100
return nil, err
101101
}
102102

103-
log.Debugf("netconf response:\n%s", ncResponse.DocAsString())
103+
log.Debugf("%s: netconf response:\n%s", t.name, ncResponse.DocAsString())
104104

105105
// cmlImport := xml.NewXmlTreeImporter(ncResponse.Doc.Root())
106106

pkg/datastore/target/netconf/xml2SchemapbAdapter.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ func (x *XML2sdcpbConfigAdapter) transformContainer(ctx context.Context, e *etre
146146
// transformField transforms an etree.element of a configuration as an update into the provided *sdcpb.Notification.
147147
func (x *XML2sdcpbConfigAdapter) transformField(ctx context.Context, e *etree.Element, pelems []*sdcpb.PathElem, ls *sdcpb.LeafSchema, result *sdcpb.Notification) error {
148148
path := pelems
149-
for ls.GetType().GetLeafref() != "" {
149+
schemaLeafType := ls.GetType()
150+
for schemaLeafType.GetLeafref() != "" {
150151
path, err := utils.NormalizedAbsPath(ls.Type.Leafref, path)
151152
if err != nil {
152153
return err
@@ -157,16 +158,18 @@ func (x *XML2sdcpbConfigAdapter) transformField(ctx context.Context, e *etree.El
157158
return err
158159
}
159160

160-
var schemaElem *sdcpb.SchemaElem_Field
161-
var ok bool
162-
if schemaElem, ok = schema.GetSchema().GetSchema().(*sdcpb.SchemaElem_Field); !ok {
163-
return fmt.Errorf("node [%s] with leafref [%s] has non-field target type [%T: %v]", e.GetPath(), ls.GetType().GetLeafref(), schema.GetSchema().GetSchema(), schema.GetSchema().GetSchema())
161+
switch se := schema.GetSchema().GetSchema().(type) {
162+
case *sdcpb.SchemaElem_Leaflist:
163+
schemaLeafType = se.Leaflist.GetType()
164+
case *sdcpb.SchemaElem_Field:
165+
schemaLeafType = se.Field.GetType()
166+
default:
167+
return fmt.Errorf("node [%s] with leafref [%s] has non-field or leaflist target type [%T]", e.GetPath(), ls.GetType().GetLeafref(), se)
164168
}
165-
ls = schemaElem.Field
166169
}
167170

168171
// process terminal values
169-
tv, err := StringElementToTypedValue(e.Text(), ls)
172+
tv, err := utils.Convert(e.Text(), schemaLeafType)
170173
if err != nil {
171174
slt, errMarsh := json.Marshal(ls.Type)
172175
if errMarsh != nil {

pkg/tree/sharedEntryAttributes.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -951,6 +951,9 @@ func (s *sharedEntryAttributes) Validate(ctx context.Context, resultChan chan<-
951951

952952
// validate the mandatory statement on this entry
953953
if s.remainsToExist() {
954+
955+
// TODO: Validate Enums
956+
954957
if !vCfg.DisabledValidators.Mandatory {
955958
s.validateMandatory(ctx, resultChan)
956959
}

pkg/tree/validation_entry_leafref.go

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,18 @@ func (s *sharedEntryAttributes) BreadthSearch(ctx context.Context, path string)
109109
// NavigateLeafRef
110110
func (s *sharedEntryAttributes) NavigateLeafRef(ctx context.Context) ([]Entry, error) {
111111

112+
// leafref path takes as an argument a string that MUST refer to a leaf or leaf-list node.
113+
// e.g.
114+
// leaf foo {
115+
// type leafref {
116+
// path "/bar/baz";
117+
// }
118+
// }
119+
// the runtime semantics are:
120+
// If /bar/baz resolves to a leaf, then foo must have exactly the same value as that leaf.
121+
// If /bar/baz resolves to a leaf-list, then foo must have a value equal to one of the existing entries in that leaf-list.
122+
// Thus, the "pointer" is not to the entire leaf-list node, but to one instance of it, selected by value.
123+
112124
var lref string
113125
switch {
114126
case s.GetSchema().GetField().GetType().GetLeafref() != "":
@@ -121,34 +133,34 @@ func (s *sharedEntryAttributes) NavigateLeafRef(ctx context.Context) ([]Entry, e
121133

122134
lv := s.leafVariants.GetHighestPrecedence(false, true)
123135

136+
// value of node with type leafref
124137
tv := lv.Value()
125-
var values []*sdcpb.TypedValue
126-
127-
switch ttv := tv.Value.(type) {
128-
case *sdcpb.TypedValue_LeaflistVal:
129-
values = append(values, ttv.LeaflistVal.GetElement()...)
130-
default:
131-
values = append(values, tv)
132-
}
133-
134-
var resultEntries []Entry
135138

136139
foundEntries, err := s.BreadthSearch(ctx, lref)
137140
if err != nil {
138141
return nil, err
139142
}
140143

141-
resultEntries = []Entry{}
144+
var resultEntries []Entry
142145

143146
for _, e := range foundEntries {
144-
145147
r, err := e.getHighestPrecedenceLeafValue(ctx)
146148
if err != nil {
147149
return nil, err
148150
}
149-
val := r.Value()
150-
for _, value := range values {
151-
if utils.EqualTypedValues(val, value) {
151+
// Value of the resolved leafref
152+
refVal := r.Value()
153+
var vals []*sdcpb.TypedValue
154+
155+
switch tVal := refVal.Value.(type) {
156+
case *sdcpb.TypedValue_LeaflistVal:
157+
vals = append(vals, tVal.LeaflistVal.GetElement()...)
158+
default:
159+
vals = append(vals, refVal)
160+
}
161+
// loop through possible values of found reference (leaf -> 1 value, leaf-list -> 1+ values)
162+
for _, val := range vals {
163+
if utils.EqualTypedValues(val, tv) {
152164
resultEntries = append(resultEntries, e)
153165
break
154166
}

pkg/utils/converter.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ func (c *Converter) ExpandUpdate(ctx context.Context, upd *sdcpb.Update) ([]*sdc
140140
}
141141
}
142142

143-
if rsp.Field.GetType().Type == "identityref" {
143+
// We expect that all identityrefs are sent by schema-server as a identityref type now, not string
144+
if rsp.Field.GetType().Type == "identityref" && upd.GetValue().GetStringVal() != "" {
144145
upd.Value, err = Convert(upd.GetValue().GetStringVal(), rsp.Field.GetType())
145146
if err != nil {
146147
return nil, err

0 commit comments

Comments
 (0)