Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

Overview

The following study describes extending YANG language statements to allow customization of models.

References:

YANG Language

  • The YANG language provides us the ability to define and model configurations and state data by defining YANG modules
    • Modules contain a sequence of statements
      • Statement syntax is either of the following :
        • statement = keyword [argument] ;
        • statement = keyword [argument] { <substatement(s)..> } ;

* argument can be zero or one depending on the statement

* argument is a string

...

container nodes

...

Sample YANG

(stores.yang)

...

languagetext
themeConfluence
linenumberstrue

...

Table of Contents

Overview

The following study describes extending YANG language statements to allow customization of models.

References:

YANG Language

  • The YANG language provides us the ability to define and model configurations and state data by defining YANG modules
    • Modules contain a sequence of statements
      • Statement syntax is either of the following :
        • statement = keyword [argument] ;
        • statement = keyword [argument] { <substatement(s)..> } ;

* argument can be zero or one depending on the statement

* argument is a string

  • An XML-based equivalent version of YANG is called YIN
  • YANG uses a tree to define the hierarchy of data wherein each ‘node’ has a value or/and a set of child nodes
    • 4 types of nodes
      • container nodes


      • list nodes 
      • leaf nodes
      • leaf-list nodes

Basic YANG statements

Sample YANG

(stores.yang)

Statements and Description


Code Block
languagetext
themeConfluence
titlestores model
linenumberstrue
module stores {
    yang-version 1.1;
    namespace "org:onap:ccsdk:sample";

    prefix book-store;

    revision "2020-09-15" {
        description
        "Sample Model";
    }

    typedef year {
        type uint16 {
            range "1000..9999";
        }
    }

    container bookstore { 

        leaf bookstore-name {
            type string;
        }
    list categories {

        key "code";

        leaf code {	
            type string;
        }

        leaf name {
            type string;
        }

        list books {
            key title;

            leaf title {
                type string;
            }
            leaf-list authors {
                type string; 
            }
        }
    }
    }
}


module Statement

see example from Line 1

  • YANG language defines models with modules and submodules
  • Takes one argument (module name) which is the identifier
  • Groups all statements that belong to the module
  • This module example contains the following statements for header information:

             see examples from Lines 2-16

      • yang-version statement
      • namespace statement prefix statement
      • revision statements



typedef Statement

see example from Line 12

  • a statement that allows a new type to be defined based on a base type which is a YANG built-in type



container Statement

see example from Line 18

  • defines interior (container node) in the schema tree
  • only contains child nodes, has no value
      • child nodes can be a leaf, lists, containers and leaf-lists



leaf Statement

see example from Line 27

  • defines a leaf node in the schema tree
  • its only one argument is the identifier
  • has no child nodes, has one value of a particular type
  • 'type statement' is mandatory
  • See optional substatements available in (Section 7.6 https://www.hjp.at/doc/rfc/rfc6020.html#sec_1)



list Statement

see example from Line 35

  • defines an interior data node (list node) in the schema tree
  • its only one argument is the identifier
  • follows a block of substatements:
  • mandatory substatements:
      • 'key statement'

leaf-list Statement

see example from Line 41

  • array of leaf nodes
  • one value of a particular type per leaf
  • its only one argument is the identifier


Figure 1.1 Schema tree of module 'stores'

Code Block
languagexml
titleSchema tree of module 'stores'
module: stores
  +--rw bookstore
     +--rw bookstore-name?   string
     +--rw categories* [code]
        +--rw code     string
        +--rw name?    string
        +--rw books* [title]
           +--rw title       string
           +--rw lang?       string
           +--rw authors*    string
        

...

   +--rw pub_year? 

...

 

...

 

...

year
         

...

 

...

 +--rw price?      

...

uint64


YANG extension Statement

Sample YANG

(stores.yang with extension)

Statements and Description


Code Block
languageyml
titlestores model with extension
linenumberstrue
module sync-extension {
…
prefix sync-ext;
…
   extension sync-flag{
   
type
 
string;
 description
       
}
    “This is a sample extension statement 
leaf
description“
name
 
{
     argument "value";
   }
type string;
}


The following model shows that it imported the model above where extensions is declared.

Code Block
languageyml
titleextended-stores model
linenumberstrue
module extended-stores {
    yang-version 
}
1.1;
	...
    import sync-extension{
	   
list
 
books {
prefix sync-ext;
	}

    typedef year {
   
key
 
title;
    
leaf title
type uint16 {
            
type string;
range "1000..9999";
        
}
    }

    container bookstore 
leaf-list authors
{
       sync-ext:sync-flag "on";
    ...
	}
type
}
string;
  




extension Statement

see example from Lines 5-9 on stores model with extension

  • Syntax
Code Block
languagetext
extension <keyword/identifier>{
     <extension 
} } } } } module Statement
substatements...>
}


  • Usage

see example from Line

1
  • YANG language defines models with modules and submodules
  • Takes one argument (module name) which is the identifier
  • Groups all statements that belong to the module
  • This module example contains the following statements for header information:

             see examples from Lines 2-16

      • yang-version statement
      • namespace statement prefix statement
      • revision statements

typedef Statement

see example from Line 12

  • a statement that allows a new type to be defined based on a base type which is a YANG built-in type

container Statement

see example from Line 18

  • defines interior (container node) in the schema tree
  • only contains child nodes, has no value
      • child nodes can be a leaf, lists, containers and leaf-lists

leaf Statement

see example from Line 27

  • defines a leaf node in the schema tree
  • its only one argument is the identifier
  • has no child nodes, has one value of a particular type
  • 'type statement' is mandatory
  • See optional substatements available in (Section 7.6 https://www.hjp.at/doc/rfc/rfc6020.html#sec_1)

list Statement

see example from Line 35

  • defines an interior data node (list node) in the schema tree
  • its only one argument is the identifier
  • follows a block of substatements:
  • mandatory substatements:
      • 'key statement'

leaf-list Statement

see example from Line 41

  • array of leaf nodes
  • one value of a particular type per leaf
  • its only one argument is the identifier

Figure 1.1 Schema tree of module 'stores'

Code Block
languagexml
titleSchema tree of module 'stores'
module: stores
  +--rw bookstore
     +--rw bookstore-name?   string
     +--rw categories* [code]
        +--rw code     string
        +--rw name?    string
        +--rw books* [title]
           +--rw title       string
           +--rw lang?       string
           +--rw authors*    string
           +--rw pub_year?   year
           +--rw price?      uint64

YANG extension Statement

module example-module2{ … import stores { prefix book-store; } book-store:sampleExtension locations { list address {

15 on extended-stores model

Sample YANG

(stores.yang with extension)

Statements and Description
  • stores model
Code Block
languageyml
linenumberstrue
module stores {
…
prefix book-store;
…
   extension sampleExtension{
     description
           “This is a sample extension statement description“
      argument name {
          yin-element true;
     }
   }
container bookstore { 
        leaf bookstore-name {
            type string;
        }
….
}

  • example-module2 model
Code Block
languageyml
linenumberstrue
Code Block
languagetext
<module prefix>:<extension keyword> "argument";


  • to be used to define new statements
  • available to be imported and used by other modules just like a normal YANG statement
      • by use of 'import statement' to import the module where the extension is defined
  • statements that do not have any substatements can have extensions defined if wanted
  • its only one argument is the identifier and keyword for the extension
  • Optional substatements:
      • argument Statement
      • description Statement
      • reference Statement
      • defined extension Statements








argument Statement

see examples from Line 6 on stores model

  • takes a string argument which is the name of the argument to the keyword
  • Optional substatement
      • yin-element Statement




Code Block
languagexml
themeMidnight
titleYIN-extended-stores model
linenumberstrue
<?xml version="1.0" encoding="UTF-8"?>
<module name="extended-stores"
        xmlns="urn:ietf:params:xml:ns:yang:yin:1"
        xmlns:ext-book-store="org:onap:ccsdk:sampleExtended"
        xmlns:book-store="org:onap:ccsdk:sample">
  <namespace uri="org:onap:ccsdk:sampleExtended"/>
  <prefix value="ext-book-store"/>
  <revision date="2020-09-15">
    <description>
      <text>Sample Extended Model</text>
    </description>
  </revision>
  <import module="sync-extension">
    <prefix value="sync-ext"/>
  </import>
  <typedef name="year">
    <type name="uint16">
      <range value="1000..9999"/>
    </type>
  </typedef>
  <container name="bookstore">
    <sync-ext:sync-flag value="on"/>
    <leaf name="bookstore-name">
      <type name="string"/>
    </leaf>
	...
  </container>
</module>


yin-element Statement

  • takes a string argument which is true or false
  • yin-element is 'false' by default
  • if the argument is 'true' it indicates that the argument is mapped to an XML element in YIN or to an XML attribute


Notes

  1. Line 22 on YIN-extended-stores model
    1. result of using the argument without specifying the yin-element value
      1. yin-element is 'false'
      2. the argument 'value' is only an XML attribute
  2. if argument statement (Line 6 on stores model) contains yin-element substatement YIN-extend-stores model would result to the following:
    1. extension statement will produce a child node

      Code Block
      themeMidnight
      titleYIN-extended-stores model where yin-element is 'true'
      ...
        <container name="bookstore">
          <sync-ext:sync-flag>
            <sync-ext:value>on</sync-ext:value>
          </sync-ext:sync-flag>
      ...
        </container>
      ...

      ** extension does not extend the data


** the YIN version and Schema trees above are generated by YANG validator 'pyang'

Existing YANG parser in CPS

(Please see https://lf-onap.atlassian.net/wiki/display/DW/Existing+Yang+Parser)

OpenDayLight Yang tools recognize YANG extensions

  • Contains interface which has methods to access data of a YANG extension statement

    Code Block
    languagejava
    themeEclipse
    titleYang tools ExtensionDefinition Interface
    package org.opendaylight.yangtools.yang.model.api;
    import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionEffectiveStatement;
    public interface ExtensionDefinition extends SchemaNode, EffectiveStatementEquivalent<ExtensionEffectiveStatement> {
        String getArgument();
        boolean isYinElement();
    }      


Test cases and scenarios

The following test cases used and modified the standard stores model seen above.

Testing with groovy

The following cases were tested in YangTextSchemaSourceSetSpec.groovy using the test method 'Building a valid YangTextSchemaSourceSet using #filenameCase filename)'.

Key

**Green cell for case number indicates that tests have passed

**Red cell for case number indicates that tests have failed

  • the extension is defined as substatement in the module with argument statement as its substatement
Case #DescriptionJAVA objectNotes
1
  • extension used inside container statement before all other substatements
Code Block
collapsetrue
module stores {
    yang-version 1.1;
	...
    extension sync-flag{
        description "This extension allows to tag nodes with a sync flag";
        
key
argument "
state
value";
    }

   
leaf
 
state
typedef year {...}

    
type string; description "State name"
container bookstore {
        
book-store:
sampleExtension
sync-
b
flag "
b-sample-name
on";
		...
        leaf bookstore-name {...}
		list categories {..}
...
}


Image Added

  • extension declared after all other substatements of container still passed
2
  • extension used inside a leaf statement (child of a container) before all other substatements
Code Block
collapsetrue
module stores {
  
}
  yang-version 1.1;
	...
    extension 
leaf
sync-flag{
city
 
{
       description "This extension allows to tag 
type
nodes 
string;
with a sync flag";
        
description
argument "
City name
value"
{
;
    }

    typedef year {...}

 
book-store:sampleExtension-c
 
"c-sample-name";
  container bookstore {
		...
      
}
 
….
 leaf bookstore-name {
}
	      

extension Statement

see example from Lines 5-11 on stores model

  • Syntax
Code Block
languagetext
extension <keyword/identifier>{
     <extension substatements...>
}
  • Usage

see example from Lines 

Code Block
languagetext
<module prefix>:<extension keyword> "argument";
  • to be used to define new statements
  • available to be imported and used by other modules just like a normal YANG statement
      • by use of 'import statement' to import the module where the extension is defined
  • statements that do not have any substatements can have extensions defined if wanted
  • its only one argument is the identifier and keyword for the extension
  • Optional substatements:
      • argument Statement
      • description Statement
      • reference Statement
      • defined extension Statements

argument Statement

see examples from Lines on stores model

  • takes a string argument which is the name of the argument to the keyword
  • Optional substatement
      • yin-element Statement
Code Block
languagexml
themeMidnight
linenumberstrue
<?xml version="1.0" encoding="UTF-8"?> <module name="example-module2" xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:em="org:onap:ccsdk:sample2" xmlns:book-store="org:onap:ccsdk:sample"> <yang-version value="1.1"/> <namespace uri="org:onap:ccsdk:sample2"/> <prefix value="em"/> <import module="stores"> <prefix value="book-store"/> </import> <book-store:sampleExtension> <book-store:name>locations</book-store:name> <list name="address"> <key value="state"/> <leaf name="state">
book-store:sync-flag "on"; 
		}
		list categories {..}
...
}


Image Added

  • Extension declared after type-statement inside leaf statement (child of a container) still passed
3
  • extension used inside list statement (child of a container) before all other substatements
Code Block
collapsetrue
module stores {
    yang-version 1.1;
	...
    extension sync-flag{
        description "This extension allows to tag nodes with a sync flag";
        argument "value";
    }

    typedef year {...}

    container bookstore {
		...
        leaf bookstore-name {...}
		list categories {
		 	book-store:sync-flag "on";
			key "code";
			...  
		}
...
}


Image Added

  • Extension declared after key-statement inside list statement (child of a container) still passed
4
  • extension used inside leaf statement (child of list node from case #3) before all its substatements
Code Block
collapsetrue
module stores {
    yang-version 1.1;
 	...
    extension sync-flag{
        description "This extension allows to tag nodes with a sync flag";
        
<type
argument 
name=
"
string
value"
/>
;
    }
   
<description>
 typedef year {...}

    container bookstore 
<text>State
{
name</text>
        
<book-store:sampleExtension-b name="b-sample-name"/>
leaf bookstore-name {...}

    list categories 
</description>
{
      
</leaf>
  
<leaf name="city">
key "code";
        
<type name="string"/>
leaf code {
      
<description>
      
book-store:sync-flag "on";
  
<text>City
 
name</text>
         type 
<book-store:sampleExtension-c>
string;
        }
    
<book-store:name>c-sample-name</book-store:name>
    leaf name {...}
    
</book-store:sampleExtension-c>
    list books {...}
</description>
...
}


Image Added

  • Extension declared after type-statement inside leaf statement (child of list node from case #3) still passed
5
  • extension used inside list node (child of list node from case #4) before key-statement of list
Code Block
collapsetrue
module stores {
    
</leaf> </list> </book-store:sampleExtension> </module>

yin-element Statement

  • takes a string argument which is true or false
  • yin-element is 'false' by default
  • if the argument is 'true' it indicates that the argument is mapped to an XML element in YIN or to an XML attribute
  1. Line 

** the YIN version and Schema trees above are generated by YANG validator 'pyang'

Expected tree diagram for example-module based on RFC8340 (https://datatracker.ietf.org/doc/html/rfc8340):

Code Block
languagetext
sampleExtension locations:
     +-- address* [state]
        +-- state string
        +-- city? string

Existing YANG parser

(Please see https://wiki.onap.org/display/DW/Existing+Yang+Parser)

OpenDayLight Yang tools recognises YANG extensions

...

package org.opendaylight.yangtools.yang.model.api;
import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionEffectiveStatement;
public interface ExtensionDefinition extends SchemaNode, EffectiveStatementEquivalent<ExtensionEffectiveStatement> {
String getArgument();
boolean isYinElement();
}

...

yang-version 1.1;
 	...
    extension sync-flag{
        description "This extension allows to tag nodes with a sync flag";
        argument "value";
    }
    typedef year {...}

    container bookstore {
        leaf bookstore-name {...}

    list categories {
        key "code";
        leaf code {...}
        leaf name {...}
        list books {
		 book-store:sync-flag "on";
		...
		}
...
}


Image Added

  • extension declared after key-statement of the list statement still passed
6
  • extension used inside leaf-list node (child of list node from case #5) before all other substatements
Code Block
collapsetrue
module stores {
    yang-version 1.1;
 	...
    extension sync-flag{
        description "This extension allows to tag nodes with a sync flag";
        argument "value";
    }
    typedef year {...}

    container bookstore {
        leaf bookstore-name {...}

    list categories {
        key "code";
        leaf code {...}
        leaf name {...}
        list books {
			leaf-list authors{
			  book-store:sync-flag "on"; 
			}
		}
...
}


Image Added

  • extension declared after type-statement of leaf-list still passed
7
  • extension used inside module
Code Block
collapsetrue
module stores {
    yang-version 1.1;
	...
    extension sync-flag{
        description "This extension allows to tag nodes with a sync flag";
        argument "value";
    }

    typedef year {...}

    book-store:sync-flag "on"; 

    container bookstore {...}
}


Image Added

  • data tree still only has one direct child (container node) as with the standard stores model
  • value of the argument is not seen?
8
  • scenario the same as case 1 but the extension was used in the container statement without an argument
Code Block
collapsetrue
module stores {
    yang-version 1.1;
	...
    extension sync-flag{
        description "This extension allows to tag nodes with a sync flag";
        argument "value";
    }

    typedef year {...}

    container bookstore {
        book-store:sync-flag;
		...
}


Image Added

  • same extension declaration/usage fails for:
      • scenarios in all cases 2-7
9
  • no argument declared for extension
Code Block
collapsetrue
module stores {
    yang-version 1.1;
	...
    extension sync-flag;

    typedef year {...}

    container bookstore {
        book-store:sync-flag;
		...
        leaf bookstore-name {...}
		list categories {..}
...
}


Image Added

  • use of the same definition and declaration of the extension on this case for cases #1-7 passes
10
  • extension used twice
    • inside container statement before all other substatements
    • inside leaf statement (child of container statement)
Code Block
collapsetrue
module stores {
    yang-version 1.1;
	...
    extension sync-flag;

    typedef year {...}

    container bookstore {
        book-store:sync-flag;
		...
        leaf bookstore-name {
			book-store:sync-flag;
		}
		list categories {..}
...
}


Image Added



Extra Notes:

  • There seems to be no inheritance of the extension statement for the substatements wherein the extension was used
  • The date tree and schema tree does not change sizes with the addition of the extensions for all cases shown above

Parsing a original data instance (json) using the extended model

Case #DescriptionResult
1
  • Created schema set
    • the model contained only an extension definition
  • successfully stored yang resource
  • successfully created a node using the model
    • fragment table did not add the extension argument in attributes
2
  • Created schema set
    • the model contained an extension definition and the model was used inside a container node
  • successfully stored yang resource
  • successfully created a node using the model
    • fragment table did not add the extension argument in attributes


*the same result acquired for all passed cases on the groovy tests table above

3
  • Created schema set
    • the model contained only an extension definition
      • extension contains argument
          • yin-element set to true
  • creating the schema set failed
    • received 500 server error parsing schema set
4
  • Created schema set
    • the model contained an extension definition and was used inside the container node
      • extension contains argument
          • yin-element set to true
  • creating the schema set failed
    • received 500 server error parsing schema set


Conclusions

  • The YANG language extension analysis above is only applicable for seeing that it is good for type configuration.
    • The extension does not extend the actual data of the model instance
    • Based on the test scenarios above, extensions can only be seen on the schema sets and not on the data
  • YANG extension can be used at every level of the tree model
  • The test results show that the model is being recognized by the current YANG tools used to parse a model
    • It fails for scenarios such as parsing a model without an argument defined when it is expecting it
  • This analysis did not look further into the effect of setting yin-element to 'true' for the model instance
  • Further investigation is required to cover interpretation as the analysis above only covers parsing
    •  see
      Jira Legacy
      serverSystem Jira
      serverId4733707d-2057-3a0f-ae5e-4fd8aff50176
      keyCPS-866