Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 24 Next »

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
stores model
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'

Schema 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


stores model with extension
module stores {
…
prefix book-store;
…
   extension sync-flag{
     description
           “This is a sample extension statement description“
      argument "value";
   }
container bookstore { 
        leaf bookstore-name {
            type string;
        }
….
}


extended-stores model
module extended-stores {
    yang-version 1.1;
	...
    import stores{
	    prefix book-store;
	}

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

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


extension Statement

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

  • Syntax
extension <keyword/identifier>{
     <extension substatements...>
}


  • Usage

see example from Line 15 on extended-stores model

<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



YIN-extended-stores model
<?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="stores">
    <prefix value="book-store"/>
  </import>
  <typedef name="year">
    <type name="uint16">
      <range value="1000..9999"/>
    </type>
  </typedef>
  <container name="bookstore">
    <book-store: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

      YIN-extended-stores model where yin-element is 'true'
      ...
        <container name="bookstore">
          <book-store:sync-flag>
            <book-store:value>on</book-store:value>
          </book-store:sync-flag>
      ...
        </container>
      ...



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

Existing YANG parser in CPS

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

OpenDayLight Yang tools recognize YANG extensions

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

    Yang 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.

Key

**Green cell for case number indicates that groovy test in YangTextSchemaSourceSetSpec.groovy 'Building a valid YangTextSchemaSourceSet using #filenameCase filename) passes

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


Case #DescriptionJAVA objectNotes
1
  • extension defined as substatement in the module with argument statement as its substatement
  • extension used inside container statement before all other substatements
  • extension contained argument
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 "on";
		...
        leaf bookstore-name {...}
		list categories {..}
...
}

  • extension declared after all other substatements of container still passed
2
  • extension defined as substatement in the module with argument statement as its substatement
  • extension used inside a leaf statement (child of a container) before all other substatements
  • extension contained argument
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 {
	      book-store:sync-flag "on"; 
		}
		list categories {..}
...
}

  • Extension declared after type-statement inside leaf statement (child of a container) still passed
3
  • extension defined as substatement in the module with argument statement as its substatement
  • extension used inside list statement (child of a container) before all other substatements
  • extension contained argument
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";
			...  
		}
...
}

  • Extension declared after key-statement inside list statement (child of a container) still passed
4
  • extension defined as substatement in the module with argument statement as its substatement
  • extension used inside leaf statement (child of list node from case #3) before all its substatements
  • extension contained argument
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 {
            book-store:sync-flag "on";
            type string;
        }
        leaf name {...}
        list books {...}
...
}

  • Extension declared after type-statement inside leaf statement (child of list node from case #3) still passed
5
  • extension defined as substatement in the module with argument statement as its substatement
  • extension used inside list node (child of list node from case #4) before key-statement of list
  • extension contained argument
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 {
		 book-store:sync-flag "on";
		...
		}
...
}

  • extension declared after key-statement of the list statement still passed
6
  • extension defined as substatement in the module with argument statement as its substatement
  • extension used inside leaf-list node (child of list node from case #5) before all other substatements
  • extension contained argument
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"; 
			}
		}
...
}

  • extension declared after type-statement of leaf-list still passed
7
  • extension defined as substatement in the module with argument statement as its substatement
  • extension used inside module
  • extension declared before container node
  • extension contained argument
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 {...}
}

  • 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
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;
		...
}

  • same extension declaration/usage fails for:
      • scenarios in all cases 2-7
9
  • extension defined as substatement in the module without argument statement as its substatement
  • extension used inside container statement before all other substatements
  • extension declared has no argument
module stores {
    yang-version 1.1;
	...
    extension sync-flag;

    typedef year {...}

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

  • use of the same definition and declaration of the extension on this case for cases #1-7 passes
10
  • extension defined as substatement in the module without argument statement as its substatement
  • extension used twice
    • inside container statement before all other substatements
    • inside leaf statement (child of container statement)
  • extension declared has no argument
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 {..}
...
}










  • No labels