WORK IN PROGRESS
This page documents the existing Yang Parser used in ONAP and OpenDayLight and will investigate if they can be used for the C&PS.
Overview
The Yang parser used in ONAP (CCSDK / SDNC) was developed (and still is) a OpenDayLight Library.
There are 2 different usage patterns within CCSDK, though.
Most of CCSDK/SDNC is using Yang primarily to define their northbound interfaces. In that context, there’s a maven plugin (org.opendaylight.yangtools:yang-maven-plugin) that is used to generate source code from the Yang model. Our application code in that case doesn’t really do anything directly with the Yang, since all of the that is handled for us by the generated code.
In ccsdk/sli/plugins, there is a plugin called restconf-client which was contributed by Huawei. That code uses the yangtool parser more directly so that it can interpret the results being returned when it calls a restconf interface.
Resources
- https://docs.opendaylight.org/en/latest/developer-guide/yang-tools.html*
- https://git.opendaylight.org/gerrit/admin/repos/yangtools
- https://gerrit.onap.org/r/admin/repos/ccsdk/sli/plugins
- https://javadoc.io/doc/org.opendaylight.yangtools
*Although this documentation link is to the latest ODL doc revision, it is very outdated and the code examples need significant updates, see findings in Mini-PoC below (bug reported: https://jira.opendaylight.org/browse/DOCS-126)
Mini-PoC
To help this evaluation I will create a small sample project with the goal to pare a yang file using the ODL Yang Tools. I will report my findings here
Maven dependency
The documentation mentioned above lists many modules but the code examples do not clarify which exactly are needed to parse a Yang file in java code.
- To be able to use yangtools teh project needs to use the mdsal 'binding-parent' pom
- The module yang-parser-impl contains all code required to parse yang files
- SLF4J has been added as the implementation requires a logger enabled
Documentation Code Updates
The sample code provided in the documentation is faulty (using == for assigning?!) and is using some long deprecated and even removed classes and methods.
Bug reported: https://jira.opendaylight.org/browse/DOCS-126
This is the kind of object (module) that gets created:
Generated Java Object Structures per Yang concept
Object Structure
The SchemaContext object generated by the Yang Parser in java has the following possible structures (java collections)
SchemaTree are implemented as a Map <QName, ? extends LeafStatement>
The Class DataSchemaNode can represent a Yang Leaf, List or Container
The interface LeafStatement provides methods for the Yang Language features including
- getType()
- getUnits()
- getMandatory()
- getWhenStatement()
- getMustStatments()
Main data types
The package org.opendaylight.yangtools.yang.model.util.type contains classes for all the possible data types including:
- BaseBinaryType
- BaseBitsType
- BaseBooleanType
- BaseDecimalType
- BaseEnumerationType
- BaseInt8Type
- BaseInt16Type
- BaseInt32Type
- BaseInt64Type
- BaseStringType
- BaseUint8Type
- BaseUint16Type
- BaseUint32Type
- BaseUint64Type
There are also some special data types such as:
- BaseEmptyType
- BaseIdentityrefType
- BaseInstanceIdentifierType
- BaseLeafrefType
- BaseUnionType
Description | Yang | Java Object View | Notes | XML Validation | JSON |
---|---|---|---|---|---|
Datatypes and basic constraints | |||||
Basic String |
| TypeStatement TypeAwareDeclaredStatement.getType() | Yes | Yes | |
Mandatory Basic String |
|
| No | No | |
Limited String | leaf pnf-name { type string { length "0..256"; } |
| Yes | Yes | |
typedef (String) with pattern |
| List<PatternConstraint> RestrictedStringType.getPatternConstraints() | Yes | Yes | |
Limited uint64 | leaf cid {325px400 type uint64 { range "0..503"; } } | Yes | Yes | ||
boolean with default value |
| N/A | N/A | ||
Unique | |||||
Unique | list server { key "name"; unique "ip port"; leaf name { type string; } leaf ip { type dotted-quad; } leaf port { type uint32; } } | No | No | ||
Choice | |||||
Choice | choice transfer-method { leaf transfer-interval { type uint64 { range "15..2880"; } units minutes; } leaf transfer-on-commit { type empty; } } | N/A | N/A | ||
Must | |||||
Must | leaf ifType { type enumeration { enum ethernet; enum atm; } } leaf ifMTU { type uint32; } must "ifType != 'ethernet' or " + "(ifType = 'ethernet' and ifMTU = 1500)" error-message 466px"An ethernet MTU must be 1500"; } | No | No | ||
When | |||||
When | leaf a { type boolean; } leaf b { type string; when "../a = 'true'"; } | No | No | ||
Extension | |||||
Extension declaration |
| N/A | |||
Extension usage | leaf attribute-with-temporal-storage { type string; cm-notify-api:store-state-ext "3 d"; } | extension is stored as 'UnknownNode' and refers back to the extension declaration | N/A | ||
Augmentation | |||||
augment "server" { when "port = '8787'"; leaf enable-debug { type boolean; } } | N/A | ||||
RPC | |||||
rpc | rpc nbrlist-change-notification { | N/A | |||
rpc input | input { in a neighbor list for this fap service"; } | N/A | |||
rpc output | output { | N/A |
Data Parsing and validation
XML Parsing
*Note: the DataSchemaNode being used when creating the XmlParserStream HAS to be the root node of the xml data!
XML Validation Findings
- The XML Parser is found to do basic data type checks including range checks and (regex) pattern validation. If the dat input doesn't conform those a clear exception detailing the problem is thrown
- Features such as 'mandatory' and 'unique' are to be validated
- More advanced features such as 'must', 'when', 'choice' etc have not yet been tested
The table in the sections above has a column with the XML validation findings.
JSON Parsing
JSON Validation Findings
- As expected the parsing of string, originating form XML or JSON is done by the same code and the results are identical to those for XML Data Parsing
Conclusions
- The YangTools model parser is comprehensive and cover all disposable Yang Language elements we might require
- complicated, no clear interface
- documentation out of data,