CiscoDevNet / ydk-gen

Generate model-driven APIs from YANG models
http://ciscodevnet.github.io/ydk-gen/
Apache License 2.0
136 stars 73 forks source link

Path API decode fails on XML payload when root_schema_node uses empty Capabilities list #1004

Open tdesh10 opened 4 years ago

tdesh10 commented 4 years ago

Expected Behavior

ydk.path.Codec.decode(root_schema_node, payload, encoding) should return the root datanode when root_schema_node uses empty Capabilities list.

Current Behavior

ydk.path.Codec.decode(root_schema_node, payload, encoding) fails with an XML payload and an empty Capabilities list. It does not fail with a JSON payload. Note that ydk.path.Codec.encode(data_node, encoding, pretty) works correctly when root_schema_node uses empty Capabilities list regardless of the encoding.

Steps to Reproduce

Execute the script below in ydk-py docker container.

Your Script

from ydk.path import Repository, Capability, Codec
from ydk.types import EncodingFormat
# import logging
# log = logging.getLogger('ydk')
# log.setLevel(logging.DEBUG)
# handler = logging.StreamHandler()
# log.addHandler(handler)

codec = Codec()
repo = Repository('/root/ydk-py/cisco-ios-xr/ydk/models/cisco_ios_xr/_yang')
root_schema = repo.create_root_schema([])

jsonfile = """{
    "Cisco-IOS-XR-cdp-cfg:cdp": {
      "timer": 10,
      "enable": true,
      "hold-time": 30,
      "log-adjacency": [null]
    }
  }
"""

xmlfile = """<cdp xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-cdp-cfg">
  <enable>true</enable>
  <hold-time>60</hold-time>
  <log-adjacency></log-adjacency>
  <timer>15</timer>
</cdp>
"""

# codec.decode(root_schema, jsonfile, EncodingFormat.JSON)
codec.decode(root_schema, xmlfile, EncodingFormat.XML)

This script produces the following output:

Traceback (most recent call last):
  File "bugtest.py", line 32, in <module>
    codec.decode(root_schema, xmlfile, EncodingFormat.XML)
RuntimeError: YCoreError: YCodecError:Data model "//cisco.com/ns/yang/Cisco-IOS-XR-cdp-cfg" not found.. Path: 

Logs

Output with DEBUG logging

Creating libyang context in path: /root/ydk-py/cisco-ios-xr/ydk/models/cisco_ios_xr/_yang
[libyang] Extension plugin "/usr/local/lib/libyang/libyang_ext_test.so" successfully loaded.
[libyang] Extension plugin "/usr/local/lib/libyang/metadata.so" successfully loaded.
[libyang] Extension plugin "/usr/local/lib/libyang/nacm.so" successfully loaded.
[libyang] Reading module "ietf-yang-metadata".
[libyang] Module "ietf-yang-metadata@2016-08-05" successfully parsed as implemented.
[libyang] Reading module "yang".
[libyang] Resolving "yang" unresolved schema nodes and their constraints...
[libyang] All "yang" schema nodes and constraints resolved.
[libyang] Module "yang@2017-02-20" successfully parsed as implemented.
[libyang] Reading module "ietf-inet-types".
[libyang] Resolving derived type "union" failed, it will be attempted later.
[libyang] Resolving derived type "union" failed, it will be attempted later.
[libyang] Resolving derived type "union" failed, it will be attempted later.
[libyang] Resolving derived type "union" failed, it will be attempted later.
[libyang] Resolving "ietf-inet-types" unresolved schema nodes and their constraints...
[libyang] All "ietf-inet-types" schema nodes and constraints resolved.
[libyang] Module "ietf-inet-types@2013-07-15" successfully parsed as implemented.
[libyang] Reading module "ietf-yang-types".
[libyang] Module "ietf-yang-types@2013-07-15" successfully parsed as implemented.
[libyang] Reading module "ietf-datastores".
[libyang] Module "ietf-datastores@2017-08-17" successfully parsed as implemented.
[libyang] Reading module "ietf-yang-library".
[libyang] Module "ietf-yang-library@2017-08-17" successfully parsed as implemented.
Populating new module schema 'ietf-yang-metadata'
Populating new module schema 'yang'
Populating new module schema 'ietf-inet-types'
Populating new module schema 'ietf-yang-types'
Populating new module schema 'ietf-datastores'
Populating new module schema 'ietf-yang-library'
ydk::path::Codec: Decoding from XML formatted payload:
<cdp xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-cdp-cfg">
  <enable>true</enable>
  <hold-time>60</hold-time>
  <log-adjacency></log-adjacency>
  <timer>15</timer>
</cdp>

Populating new schema from payload:
<cdp xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-cdp-cfg">
  <enable>true</enable>
  <hold-time>60</hold-time>
  <log-adjacency></log-adjacency>
  <timer>15</timer>
</cdp>

Extracting module namespaces from XML payload
Loading module '//cisco.com/ns/yang/Cisco-IOS-XR-cdp-cfg', revision ''
[libyang] Searching for "//cisco.com/ns/yang/Cisco-IOS-XR-cdp-cfg" in /root/ydk-py/cisco-ios-xr/ydk/models/cisco_ios_xr/_yang.
[libyang] Searching for "//cisco.com/ns/yang/Cisco-IOS-XR-cdp-cfg" in /root/ydk-py/cisco-ios-xr/ydk/models/cisco_ios_xr/_yang/ietf@0.1.5-post2.
[libyang] Searching for "//cisco.com/ns/yang/Cisco-IOS-XR-cdp-cfg" in /root/ydk-py/pathapi-taran.
Data is invalid according to the yang model. Libyang error: Data model "//cisco.com/ns/yang/Cisco-IOS-XR-cdp-cfg" not found.
Parsing failed with message Data model "//cisco.com/ns/yang/Cisco-IOS-XR-cdp-cfg" not found.
Traceback (most recent call last):
  File "bugtest.py", line 32, in <module>
    codec.decode(root_schema, xmlfile, EncodingFormat.XML)
RuntimeError: YCoreError: YCodecError:Data model "//cisco.com/ns/yang/Cisco-IOS-XR-cdp-cfg" not found.. Path: 

System Information

ydk (0.8.3) docker run -it ydkdev/ydk-py

ygorelik commented 4 years ago

This is not a bug. This is the case where you have to supply to _create_rootschema function not only capabilities, but a lookup table as well. These parameters are needed to give YDK mapping of namespaces to YANG module names. In case of JSON encoding the module names are explicitly specified in payload, which allows user create root schema with empty capabilities.

111pontes commented 4 years ago

Repository already has all YANG files and can auto-generate such mapping if not specified by the user. There's no reason to ask the user to provide such info if the YANG files have been specified already.

ygorelik commented 4 years ago

The auto-generation of lookup table is not implemented in YDK. The auto-generation of capabilities list seems not doable, because it requires user knowledge of application of if-features and deviations. The last makes the whole auto-generation idea not reliable. It can be used in first iteration, but not in production applications.