Merge "Make distributionManagement reference groups"
authorTony Tkacik <ttkacik@cisco.com>
Tue, 21 Jan 2014 13:29:37 +0000 (13:29 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 21 Jan 2014 13:29:37 +0000 (13:29 +0000)
pom.xml
yang/yang-parser-impl/pom.xml
yang/yang-parser-impl/src/main/antlr/YangParser.g4
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/TestUtils.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/TwoRevisionsTest.java [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/ietf/network-topology@2013-07-12.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/ietf/network-topology@2013-10-21.yang [new file with mode: 0644]

diff --git a/pom.xml b/pom.xml
index f770c4720bb7f1d3a936aa2c5c0f8a033d9b1dd9..66d9e506e0dea33d3c7b4121bd59c56bf923b1ce 100644 (file)
--- a/pom.xml
+++ b/pom.xml
                 <version>${mockito.version}</version>
                 <scope>test</scope>
             </dependency>
+            <dependency>
+                <groupId>org.slf4j</groupId>
+                <artifactId>slf4j-simple</artifactId>
+                <version>${slf4j.version}</version>
+                <scope>test</scope>
+            </dependency>
 
             <!-- Supporting Libraries -->
             <dependency>
         </dependencies>
     </dependencyManagement>
 
+    <dependencies>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+        </dependency>
+    </dependencies>
+
     <distributionManagement>
         <!-- OpenDayLight Released artifact -->
         <repository>
                     <groupId>org.apache.maven.plugins</groupId>
                     <artifactId>maven-release-plugin</artifactId>
                     <version>${maven.release.version}</version>
+
+                    <!-- Since we have a maven plugin, we need to install it -->
+                    <configuration>
+                        <preparationGoals>clean install</preparationGoals>
+                        <completionGoals>clean install</completionGoals>
+                    </configuration>
                 </plugin>
             </plugins>
         </pluginManagement>
index 6bbb1a4e3c46332be80e2bd260e9324e5c57a6ba..ca6ace089aaac9407c12058b81a427c17546645b 100644 (file)
             <artifactId>antlr4-runtime</artifactId>
             <version>4.0</version>
         </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-simple</artifactId>
-            <version>1.7.2</version>
-            <scope>test</scope>
-        </dependency>
         <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-all</artifactId>
index 977887ffe0c8c56bf858da04c3b313d16d12a8ff..5f8ca887aa891edfa13c405c5265384212893ddc 100644 (file)
@@ -15,7 +15,39 @@ yang : module_stmt | submodule_stmt ;
 string : STRING (PLUS STRING)*;
 
 identifier_stmt : IDENTIFIER string? stmtend;
-                  
+unknown_statement : (YIN_ELEMENT_KEYWORD | YANG_VERSION_KEYWORD | WHEN_KEYWORD | VALUE_KEYWORD | USES_KEYWORD | UNITS_KEYWORD | UNIQUE_KEYWORD | 
+                    TYPEDEF_KEYWORD | TYPE_KEYWORD | SUBMODULE_KEYWORD | RPC_KEYWORD | REVISION_DATE_KEYWORD | REVISION_KEYWORD | 
+                    REQUIRE_INSTANCE_KEYWORD | REFINE_KEYWORD | RANGE_KEYWORD | PRESENCE_KEYWORD | PREFIX_KEYWORD | 
+                    POSITION_KEYWORD | PATTERN_KEYWORD | PATH_KEYWORD | OUTPUT_KEYWORD | ORGANIZATION_KEYWORD|  ORDERED_BY_KEYWORD | NOTIFICATION_KEYWORD| 
+                    NAMESPACE_KEYWORD | MUST_KEYWORD | MODULE_KEYWORD | MIN_ELEMENTS_KEYWORD | MAX_ELEMENTS_KEYWORD | MANDATORY_KEYWORD | LIST_KEYWORD | 
+                    LENGTH_KEYWORD | LEAF_LIST_KEYWORD | LEAF_KEYWORD | KEY_KEYWORD | INPUT_KEYWORD | INCLUDE_KEYWORD | IMPORT_KEYWORD | IF_FEATURE_KEYWORD | 
+                    IDENTITY_KEYWORD | GROUPING_KEYWORD | FRACTION_DIGITS_KEYWORD | FEATURE_KEYWORD | DEVIATE_KEYWORD | DEVIATION_KEYWORD | EXTENSION_KEYWORD | 
+                    ERROR_MESSAGE_KEYWORD | ERROR_APP_TAG_KEYWORD | ENUM_KEYWORD | DEFAULT_KEYWORD | CONTAINER_KEYWORD | CONTACT_KEYWORD | 
+                    CONFIG_KEYWORD | CHOICE_KEYWORD |  CASE_KEYWORD | BIT_KEYWORD | BELONGS_TO_KEYWORD | BASE_KEYWORD | AUGMENT_KEYWORD |  
+                    ANYXML_KEYWORD | IDENTIFIER) string? (SEMICOLON | (LEFT_BRACE unknown_statement2* RIGHT_BRACE));
+
+unknown_statement2 : (YANG_VERSION_KEYWORD | WHEN_KEYWORD | VALUE_KEYWORD | USES_KEYWORD | UNITS_KEYWORD | UNIQUE_KEYWORD | 
+                    TYPEDEF_KEYWORD | TYPE_KEYWORD | SUBMODULE_KEYWORD | STATUS_KEYWORD | RPC_KEYWORD | REVISION_DATE_KEYWORD | REVISION_KEYWORD | 
+                    REQUIRE_INSTANCE_KEYWORD | REFINE_KEYWORD | REFERENCE_KEYWORD | RANGE_KEYWORD | PRESENCE_KEYWORD | PREFIX_KEYWORD | 
+                    POSITION_KEYWORD | PATTERN_KEYWORD | PATH_KEYWORD | OUTPUT_KEYWORD | ORGANIZATION_KEYWORD|  ORDERED_BY_KEYWORD | NOTIFICATION_KEYWORD| 
+                    NAMESPACE_KEYWORD | MUST_KEYWORD | MODULE_KEYWORD | MIN_ELEMENTS_KEYWORD | MAX_ELEMENTS_KEYWORD | MANDATORY_KEYWORD | LIST_KEYWORD | 
+                    LENGTH_KEYWORD | LEAF_LIST_KEYWORD | LEAF_KEYWORD | KEY_KEYWORD | INPUT_KEYWORD | INCLUDE_KEYWORD | IMPORT_KEYWORD | IF_FEATURE_KEYWORD | 
+                    IDENTITY_KEYWORD | GROUPING_KEYWORD | FRACTION_DIGITS_KEYWORD | FEATURE_KEYWORD | DEVIATE_KEYWORD | DEVIATION_KEYWORD | EXTENSION_KEYWORD | 
+                    ERROR_MESSAGE_KEYWORD | ERROR_APP_TAG_KEYWORD | ENUM_KEYWORD | DESCRIPTION_KEYWORD | DEFAULT_KEYWORD | CONTAINER_KEYWORD | CONTACT_KEYWORD | 
+                    CONFIG_KEYWORD | CHOICE_KEYWORD |  CASE_KEYWORD | BIT_KEYWORD | BELONGS_TO_KEYWORD | BASE_KEYWORD | AUGMENT_KEYWORD | ARGUMENT_KEYWORD | 
+                    ANYXML_KEYWORD | IDENTIFIER) string? (SEMICOLON | (LEFT_BRACE unknown_statement3* RIGHT_BRACE));
+
+unknown_statement3 : (YIN_ELEMENT_KEYWORD | YANG_VERSION_KEYWORD | WHEN_KEYWORD | VALUE_KEYWORD | USES_KEYWORD | UNITS_KEYWORD | UNIQUE_KEYWORD | 
+                    TYPEDEF_KEYWORD | TYPE_KEYWORD | SUBMODULE_KEYWORD | STATUS_KEYWORD | RPC_KEYWORD | REVISION_DATE_KEYWORD | REVISION_KEYWORD | 
+                    REQUIRE_INSTANCE_KEYWORD | REFINE_KEYWORD | REFERENCE_KEYWORD | RANGE_KEYWORD | PRESENCE_KEYWORD | PREFIX_KEYWORD | 
+                    POSITION_KEYWORD | PATTERN_KEYWORD | PATH_KEYWORD | OUTPUT_KEYWORD | ORGANIZATION_KEYWORD|  ORDERED_BY_KEYWORD | NOTIFICATION_KEYWORD| 
+                    NAMESPACE_KEYWORD | MUST_KEYWORD | MODULE_KEYWORD | MIN_ELEMENTS_KEYWORD | MAX_ELEMENTS_KEYWORD | MANDATORY_KEYWORD | LIST_KEYWORD | 
+                    LENGTH_KEYWORD | LEAF_LIST_KEYWORD | LEAF_KEYWORD | KEY_KEYWORD | INPUT_KEYWORD | INCLUDE_KEYWORD | IMPORT_KEYWORD | IF_FEATURE_KEYWORD | 
+                    IDENTITY_KEYWORD | GROUPING_KEYWORD | FRACTION_DIGITS_KEYWORD | FEATURE_KEYWORD | DEVIATE_KEYWORD | DEVIATION_KEYWORD | EXTENSION_KEYWORD | 
+                    ERROR_MESSAGE_KEYWORD | ERROR_APP_TAG_KEYWORD | ENUM_KEYWORD | DESCRIPTION_KEYWORD | DEFAULT_KEYWORD | CONTAINER_KEYWORD | CONTACT_KEYWORD | 
+                    CONFIG_KEYWORD | CHOICE_KEYWORD |  CASE_KEYWORD | BIT_KEYWORD | BELONGS_TO_KEYWORD | BASE_KEYWORD | AUGMENT_KEYWORD | ARGUMENT_KEYWORD | 
+                    ANYXML_KEYWORD | IDENTIFIER) string? (SEMICOLON | (LEFT_BRACE unknown_statement3* RIGHT_BRACE));
+
 stmtend : (SEMICOLON) | (LEFT_BRACE identifier_stmt? RIGHT_BRACE);
 deviate_replace_stmt : DEVIATE_KEYWORD string /* REPLACE_KEYWORD */ (SEMICOLON | (LEFT_BRACE (identifier_stmt |type_stmt | units_stmt | default_stmt | config_stmt | mandatory_stmt | min_elements_stmt | max_elements_stmt )* RIGHT_BRACE));
 deviate_delete_stmt : DEVIATE_KEYWORD string /* DELETE_KEYWORD */ (SEMICOLON | (LEFT_BRACE (identifier_stmt |units_stmt | must_stmt | unique_stmt | default_stmt )* RIGHT_BRACE));
@@ -97,8 +129,8 @@ base_stmt : BASE_KEYWORD string stmtend;
 identity_stmt : IDENTITY_KEYWORD string (SEMICOLON | (LEFT_BRACE  (identifier_stmt | base_stmt | status_stmt | description_stmt | reference_stmt )* RIGHT_BRACE));
 yin_element_arg : string; // TRUE_KEYWORD | FALSE_KEYWORD;
 yin_element_stmt : YIN_ELEMENT_KEYWORD yin_element_arg stmtend;
-argument_stmt : ARGUMENT_KEYWORD string (SEMICOLON | (LEFT_BRACE  (identifier_stmt)? (yin_element_stmt )? (identifier_stmt)* RIGHT_BRACE));
-extension_stmt : EXTENSION_KEYWORD string (SEMICOLON | (LEFT_BRACE  (identifier_stmt | argument_stmt | status_stmt | description_stmt | reference_stmt )* RIGHT_BRACE));
+argument_stmt : ARGUMENT_KEYWORD string (SEMICOLON | (LEFT_BRACE  (unknown_statement2)? (yin_element_stmt)? RIGHT_BRACE));
+extension_stmt : EXTENSION_KEYWORD string (SEMICOLON | (LEFT_BRACE  (unknown_statement | argument_stmt | status_stmt | description_stmt | reference_stmt )* RIGHT_BRACE));
 revision_date_stmt : REVISION_DATE_KEYWORD string stmtend;
 revision_stmt : REVISION_KEYWORD string (SEMICOLON | (LEFT_BRACE  (description_stmt )? (reference_stmt )? RIGHT_BRACE));
 units_stmt : UNITS_KEYWORD string stmtend;
index 760d0407ed77aa55916b7c81d607e18f03c360c9..e66a8dc0b0da0240c65f76cf15fe33055eac63e7 100644 (file)
@@ -25,6 +25,10 @@ final class TestUtils {
 
     public static Set<Module> loadModules(String resourceDirectory) throws FileNotFoundException {
         YangModelParser parser = new YangParserImpl();
+        return loadModules(resourceDirectory, parser);
+    }
+
+    public static Set<Module> loadModules(String resourceDirectory, YangModelParser parser) throws FileNotFoundException {
         final File testDir = new File(resourceDirectory);
         final String[] fileList = testDir.list();
         final List<File> testFiles = new ArrayList<>();
@@ -191,4 +195,14 @@ final class TestUtils {
         }
     }
 
+    public static List<Module> findModules(Set<Module> modules, String moduleName) {
+        List<Module> result = new ArrayList<>();
+        for (Module module : modules) {
+            if (module.getName().equals(moduleName)) {
+                result.add(module);
+            }
+        }
+        return result;
+    }
+
 }
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/TwoRevisionsTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/TwoRevisionsTest.java
new file mode 100644 (file)
index 0000000..05a669d
--- /dev/null
@@ -0,0 +1,28 @@
+package org.opendaylight.yangtools.yang.parser.impl;
+
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+
+public class TwoRevisionsTest {
+
+    @Test
+    public void testTwoRevisions() throws Exception {
+        YangModelParser parser = new YangParserImpl();
+
+        Set<Module> modules = TestUtils.loadModules(getClass().getResource("/ietf").getPath(), parser);
+        assertEquals(2, TestUtils.findModules(modules, "network-topology").size());
+
+        SchemaContext schemaContext = parser.resolveSchemaContext(modules);
+        assertEquals(2, TestUtils.findModules(schemaContext.getModules(), "network-topology").size());
+
+    }
+
+}
diff --git a/yang/yang-parser-impl/src/test/resources/ietf/network-topology@2013-07-12.yang b/yang/yang-parser-impl/src/test/resources/ietf/network-topology@2013-07-12.yang
new file mode 100644 (file)
index 0000000..833b9fd
--- /dev/null
@@ -0,0 +1,316 @@
+module network-topology  {
+    yang-version 1;
+    namespace "urn:TBD:params:xml:ns:yang:network-topology";
+    // replace with IANA namespace when assigned
+    prefix "nt";
+
+    import ietf-inet-types { prefix "inet"; }
+
+    organization "TBD";
+
+    contact "WILL-BE-DEFINED-LATER";
+/*
+    description 
+        "This module defines a model for the topology of a network.
+        Key design decisions are as follows:
+        A topology consists of a set of nodes and links.  
+        Links are point-to-point and unidirectional.  
+        Bidirectional connections need to be represented through
+        two separate links.  
+        Multipoint connections, broadcast domains etc can be represented 
+        through a hierarchy of nodes, then connecting nodes at 
+        upper layers of the hierarchy.";  
+*/
+    revision 2013-07-12 {
+        description
+            "Initial revision.";
+    }
+        
+    typedef topology-id {
+        type inet:uri;
+        description 
+            "An identifier for a topology.";
+    }
+
+    typedef node-id {
+        type inet:uri;
+        description
+            "An identifier for a node in a topology.  
+            The identifier may be opaque.  
+            The identifier SHOULD be chosen such that the same node in a 
+            real network topology will always be identified through the 
+            same identifier, even if the model is instantiated in separate 
+            datastores. An implementation MAY choose to capture semantics 
+            in the identifier, for example to indicate the type of node 
+            and/or the type of topology that the node is a part of.";  
+    }
+
+    typedef link-id {
+        type inet:uri;
+        description
+            "An identifier for a link in a topology.  
+            The identifier may be opaque.  
+            The identifier SHOULD be chosen such that the same link in a 
+            real network topology will always be identified through the 
+            same identifier, even if the model is instantiated in separate 
+            datastores. An implementation MAY choose to capture semantics 
+            in the identifier, for example to indicate the type of link 
+            and/or the type of topology that the link is a part of.";  
+    }
+
+    typedef tp-id {
+        type inet:uri;
+        description 
+            "An identifier for termination points on a node. 
+            The identifier may be opaque.  
+            The identifier SHOULD be chosen such that the same TP in a 
+            real network topology will always be identified through the 
+            same identifier, even if the model is instantiated in separate 
+            datastores. An implementation MAY choose to capture semantics 
+            in the identifier, for example to indicate the type of TP 
+            and/or the type of node and topology that the TP is a part of.";  
+    }
+
+    typedef tp-ref {
+        type leafref {
+            path "/network-topology/topology/node/termination-point/tp-id";
+        }
+        description 
+            "A type for an absolute reference to a termination point.
+            (This type should not be used for relative references.
+            In such a case, a relative path should be used instead.)";
+    }
+    typedef topology-ref {
+        type leafref {
+            path "/network-topology/topology/topology-id";
+        }
+        description 
+            "A type for an absolute reference a topology instance.";
+    }
+    
+    typedef node-ref {
+        type leafref {
+            path "/network-topology/topology/node/node-id";
+        }
+        description 
+            "A type for an absolute reference to a node instance.
+            (This type should not be used for relative references.
+            In such a case, a relative path should be used instead.)";
+    }
+
+    typedef link-ref {
+        type leafref {
+            path "/network-topology/topology/link/link-id";
+        }
+        description 
+            "A type for an absolute reference a link instance.
+            (This type should not be used for relative references.
+            In such a case, a relative path should be used instead.)";
+    }
+
+    grouping tp-attributes {
+        description 
+            "The data objects needed to define a termination point.
+            (This only includes a single leaf at this point, used
+            to identify the termination point.)  
+            Provided in a grouping so that in addition to the datastore,
+            the data can also be included in notifications.";
+        leaf tp-id {
+            type tp-id;
+        }
+        leaf-list tp-ref {
+            type tp-ref;
+            config false;
+            description 
+                "The leaf list identifies any termination points that the 
+                termination point is dependent on, or maps onto.  
+                Those termination points will themselves be contained 
+                in a supporting node.  
+                This dependency information can be inferred from 
+                the dependencies between links.  For this reason, 
+                this item is not separately configurable.  Hence no
+                corresponding constraint needs to be articulated.  
+                The corresponding information is simply provided by the
+                implementing system.";
+        }
+    } 
+    
+    grouping node-attributes {
+        description
+            "The data objects needed to define a node.
+            The objects are provided in a grouping so that in addition to
+            the datastore, the data can also be included in notifications
+            as needed.";
+        leaf node-id {
+            type node-id;
+            description 
+                "The identifier of a node in the topology.  
+                A node is specific to a topology to which it belongs.";   
+        }
+        list supporting-node {
+            description 
+                "This list defines vertical layering information for nodes. 
+                It allows to capture for any given node, which node (or nodes)
+                in the corresponding underlay topology it maps onto.  
+                A node can map to zero, one, or more nodes below it;
+                accordingly there can be zero, one, or more elements in the list.
+                If there are specific layering requirements, for example
+                specific to a particular type of topology that only allows
+                for certain layering relationships, the choice
+                below can be augmented with additional cases.
+                A list has been chosen rather than a leaf-list in order 
+                to provide room for augmentations, e.g. for 
+                statistics or priorization information associated with 
+                supporting nodes.";
+            key "node-ref";
+            leaf node-ref {
+                type node-ref;
+            }
+        }
+    }
+            
+    grouping link-attributes {
+        // This is a grouping, not defined inline with the link definition itself,
+        // so it can be included in a notification, if needed
+        leaf link-id {
+            type link-id;
+            description
+                "The identifier of a link in the topology.  
+                A link is specific to a topology to which it belongs.";   
+        }
+        container source { 
+            leaf source-node {
+                mandatory true;
+                type node-ref; 
+                description 
+                    "Source node identifier, must be in same topology.";
+            }
+            leaf source-tp {
+                type tp-ref; 
+                description 
+                    "Termination point within source node that terminates the link.";           
+            }
+        }
+        container destination { 
+            leaf dest-node {
+                mandatory true;
+                type node-ref; 
+                description 
+                    "Destination node identifier, must be in same topology.";
+            }
+            leaf dest-tp {
+                type tp-ref;
+                description 
+                    "Termination point within destination node that terminates the link.";
+            }
+        }
+        list supporting-link {
+            key "link-ref";
+            leaf link-ref {
+                type link-ref;
+            }
+        }
+    }
+    
+
+    container network-topology {
+        list topology {
+            description "
+                This is the model of an abstract topology.
+                A topology contins nodes and links.  
+                Each topology MUST be identified by
+                unique topology-id for reason that a network could contain many
+                topologies.
+            ";
+            key "topology-id";
+            leaf topology-id {
+                type topology-id; 
+                description "
+                    It is presumed that a datastore will contain many topologies. To
+                    distinguish between topologies it is vital to have UNIQUE
+                    topology identifiers.
+                ";
+            }
+            container topology-types {
+                description 
+                    "This container is used to identify the type, or types 
+                    (as a topology can support several types simultaneously), 
+                    of the topology.  
+                    Topology types are the subject of several integrity constraints 
+                    that an implementing server can validate in order to 
+                    maintain integrity of the datastore.  
+                    Topology types are indicated through separate data nodes; 
+                    the set of topology types is expected to increase over time.
+                    To add support for a new topology, an augmenting module
+                    needs to augment this container with a new empty optional 
+                    container to indicate the new topology type.  
+                    The use of a container allows to indicate a subcategorization
+                    of topology types.  
+                    The container SHALL NOT be augmented with any data nodes 
+                    that serve a purpose other than identifying a particular 
+                    topology type.  
+                ";
+            }   
+            list underlay-topology {
+                key "topology-ref";
+                leaf topology-ref {
+                    type topology-ref;
+                }  
+                // a list, not a leaf-list, to allow for potential augmentation 
+                // with properties specific to the underlay topology, 
+                // such as statistics, preferences, or cost.  
+                description 
+                    "Identifies the topology, or topologies, that this topology
+                    is dependent on.";
+            }
+            
+            list node {
+                description "The list of network nodes defined for the topology.";
+                key "node-id";
+                uses node-attributes;
+                must "boolean(../underlay-topology[*]/node[./supporting-nodes/node-ref])";
+                    // This constraint is meant to ensure that a referenced node is in fact 
+                    // a node in an underlay topology.  
+                list termination-point {
+                    description
+                        "A termination point can terminate a link.  
+                        Depending on the type of topology, a termination point could, 
+                        for example, refer to a port or an interface."; 
+                    key "tp-id";
+                    uses tp-attributes;
+                }
+            }
+            
+            list link {
+                description "
+                    A Network Link connects a by Local (Source) node and
+                    a Remote (Destination) Network Nodes via a set of the 
+                    nodes' termination points. 
+                    As it is possible to have several links between the same
+                    source and destination nodes, and as a link could potentially
+                    be re-homed between termination points, to ensure that we 
+                    would always know to distinguish between links, every link 
+                    is identified by a dedicated link identifier.  
+                    Note that a link models a point-to-point link, not a multipoint
+                    link.  
+                    Layering dependencies on links in underlay topologies are
+                    not represented as the layering information of nodes and of 
+                    termination points is sufficient.  
+                ";
+                key "link-id";
+                uses link-attributes;
+                must "boolean(../underlay-topology/link[./supporting-link]";
+                    // Constraint: any supporting link must be part of an underlay topology
+                must "boolean(../node[./source/source-node])";
+                    // Constraint: A link must have as source a node of the same topology
+                must "boolean(../node[./destination/dest-node])";
+                    // Constraint: A link must have as source a destination of the same topology
+                must "boolean(../node/termination-point[./source/source-tp])";
+                    // Constraint: The source termination point must be contained in the source node
+                must "boolean(../node/termination-point[./destination/dest-tp])";
+                    // Constraint: The destination termination point must be contained 
+                    // in the destination node
+            }
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/ietf/network-topology@2013-10-21.yang b/yang/yang-parser-impl/src/test/resources/ietf/network-topology@2013-10-21.yang
new file mode 100644 (file)
index 0000000..19d9b85
--- /dev/null
@@ -0,0 +1,334 @@
+module network-topology  {
+    yang-version 1;
+    namespace "urn:TBD:params:xml:ns:yang:network-topology";
+    // replace with IANA namespace when assigned
+    prefix "nt";
+
+    import ietf-inet-types { prefix "inet"; revision-date 2010-09-24; }
+
+    organization "TBD";
+
+    contact "WILL-BE-DEFINED-LATER";
+
+    description
+        "This module defines a model for the topology of a network.
+        Key design decisions are as follows:
+        A topology consists of a set of nodes and links.
+        Links are point-to-point and unidirectional.
+        Bidirectional connections need to be represented through
+        two separate links.
+        Multipoint connections, broadcast domains etc can be represented
+        through a hierarchy of nodes, then connecting nodes at
+        upper layers of the hierarchy.";
+
+    revision 2013-10-21 {
+        description
+            "Initial revision.";
+    }
+
+    typedef topology-id {
+        type inet:uri;
+        description
+            "An identifier for a topology.";
+    }
+
+    typedef node-id {
+        type inet:uri;
+        description
+            "An identifier for a node in a topology.
+            The identifier may be opaque.
+            The identifier SHOULD be chosen such that the same node in a
+            real network topology will always be identified through the
+            same identifier, even if the model is instantiated in separate
+            datastores. An implementation MAY choose to capture semantics
+            in the identifier, for example to indicate the type of node
+            and/or the type of topology that the node is a part of.";
+    }
+
+
+    typedef link-id {
+        type inet:uri;
+        description
+            "An identifier for a link in a topology.
+            The identifier may be opaque.
+            The identifier SHOULD be chosen such that the same link in a
+            real network topology will always be identified through the
+            same identifier, even if the model is instantiated in separate
+            datastores. An implementation MAY choose to capture semantics
+            in the identifier, for example to indicate the type of link
+            and/or the type of topology that the link is a part of.";
+    }
+
+    typedef tp-id {
+        type inet:uri;
+        description
+            "An identifier for termination points on a node.
+            The identifier may be opaque.
+            The identifier SHOULD be chosen such that the same TP in a
+            real network topology will always be identified through the
+            same identifier, even if the model is instantiated in separate
+            datastores. An implementation MAY choose to capture semantics
+            in the identifier, for example to indicate the type of TP
+            and/or the type of node and topology that the TP is a part of.";
+    }
+
+    typedef tp-ref {
+        type leafref {
+            path "/network-topology/topology/node/termination-point/tp-id";
+        }
+        description
+            "A type for an absolute reference to a termination point.
+            (This type should not be used for relative references.
+            In such a case, a relative path should be used instead.)";
+    }
+    typedef topology-ref {
+        type leafref {
+            path "/network-topology/topology/topology-id";
+        }
+        description
+            "A type for an absolute reference a topology instance.";
+    }
+
+    typedef node-ref {
+        type leafref {
+            path "/network-topology/topology/node/node-id";
+        }
+        description
+
+            "A type for an absolute reference to a node instance.
+            (This type should not be used for relative references.
+            In such a case, a relative path should be used instead.)";
+    }
+
+    typedef link-ref {
+        type leafref {
+            path "/network-topology/topology/link/link-id";
+        }
+        description
+            "A type for an absolute reference a link instance.
+            (This type should not be used for relative references.
+            In such a case, a relative path should be used instead.)";
+    }
+
+    grouping tp-attributes {
+        description
+            "The data objects needed to define a termination point.
+            (This only includes a single leaf at this point, used
+            to identify the termination point.)
+            Provided in a grouping so that in addition to the datastore,
+            the data can also be included in notifications.";
+        leaf tp-id {
+            type tp-id;
+        }
+        leaf-list tp-ref {
+            type tp-ref;
+            config false;
+            description
+                "The leaf list identifies any termination points that the
+                termination point is dependent on, or maps onto.
+                Those termination points will themselves be contained
+                in a supporting node.
+                This dependency information can be inferred from
+                the dependencies between links.  For this reason,
+                this item is not separately configurable.  Hence no
+                corresponding constraint needs to be articulated.
+                The corresponding information is simply provided by the
+                implementing system.";
+        }
+    }
+
+    grouping node-attributes {
+        description
+            "The data objects needed to define a node.
+            The objects are provided in a grouping so that in addition to
+            the datastore, the data can also be included in notifications
+            as needed.";
+
+        leaf node-id {
+            type node-id;
+            description
+                "The identifier of a node in the topology.
+                A node is specific to a topology to which it belongs.";
+        }
+        list supporting-node {
+            description
+                "This list defines vertical layering information for nodes.
+                It allows to capture for any given node, which node (or nodes)
+                in the corresponding underlay topology it maps onto.
+                A node can map to zero, one, or more nodes below it;
+                accordingly there can be zero, one, or more elements in the list.
+                If there are specific layering requirements, for example
+                specific to a particular type of topology that only allows
+                for certain layering relationships, the choice
+                below can be augmented with additional cases.
+                A list has been chosen rather than a leaf-list in order
+                to provide room for augmentations, e.g. for
+                statistics or priorization information associated with
+                supporting nodes.";
+            key "node-ref";
+            leaf node-ref {
+                type node-ref;
+            }
+        }
+    }
+
+    grouping link-attributes {
+        // This is a grouping, not defined inline with the link definition itself,
+        // so it can be included in a notification, if needed
+        leaf link-id {
+            type link-id;
+            description
+                "The identifier of a link in the topology.
+                A link is specific to a topology to which it belongs.";
+        }
+        container source {
+            leaf source-node {
+                mandatory true;
+                type node-ref;
+                description
+                    "Source node identifier, must be in same topology.";
+            }
+            leaf source-tp {
+                type tp-ref;
+                description
+                    "Termination point within source node that terminates the link.";
+
+            }
+        }
+        container destination {
+            leaf dest-node {
+                mandatory true;
+                type node-ref;
+                description
+                    "Destination node identifier, must be in same topology.";
+            }
+            leaf dest-tp {
+                type tp-ref;
+                description
+                    "Termination point within destination node that terminates the link.";
+            }
+        }
+        list supporting-link {
+            key "link-ref";
+            leaf link-ref {
+                type link-ref;
+            }
+        }
+    }
+
+
+    container network-topology {
+        list topology {
+            description "
+                This is the model of an abstract topology.
+                A topology contains nodes and links.
+                Each topology MUST be identified by
+                unique topology-id for reason that a network could contain many
+                topologies.
+            ";
+            key "topology-id";
+            leaf topology-id {
+                type topology-id;
+                description "
+                    It is presumed that a datastore will contain many topologies. To
+                    distinguish between topologies it is vital to have UNIQUE
+                    topology identifiers.
+                ";
+            }
+            leaf server-provided {
+                type boolean;
+                config false;
+                description "
+                    Indicates whether the topology is configurable by clients,
+                    or whether it is provided by the server.  This leaf is
+
+                    populated by the server implementing the model.
+                    It is set to false for topologies that are created by a client;
+                    it is set to true otherwise.  If it is set to true, any
+                    attempt to edit the topology MUST be rejected.
+                ";
+            }
+            container topology-types {
+                description
+                    "This container is used to identify the type, or types
+                    (as a topology can support several types simultaneously),
+                    of the topology.
+                    Topology types are the subject of several integrity constraints
+                    that an implementing server can validate in order to
+                    maintain integrity of the datastore.
+                    Topology types are indicated through separate data nodes;
+                    the set of topology types is expected to increase over time.
+                    To add support for a new topology, an augmenting module
+                    needs to augment this container with a new empty optional
+                    container to indicate the new topology type.
+                    The use of a container allows to indicate a subcategorization
+                    of topology types.
+                    The container SHALL NOT be augmented with any data nodes
+                    that serve a purpose other than identifying a particular
+                    topology type.
+                ";
+            }
+            list underlay-topology {
+                key "topology-ref";
+                leaf topology-ref {
+                    type topology-ref;
+                }
+                // a list, not a leaf-list, to allow for potential augmentation
+                // with properties specific to the underlay topology,
+                // such as statistics, preferences, or cost.
+                description
+                    "Identifies the topology, or topologies, that this topology
+                    is dependent on.";
+            }
+
+            list node {
+                description "The list of network nodes defined for the topology.";
+                key "node-id";
+                uses node-attributes;
+                must "boolean(../underlay-topology[*]/node[./supporting-nodes/node-ref])";
+                    // This constraint is meant to ensure that a referenced node is in fact
+                    // a node in an underlay topology.
+                list termination-point {
+                    description
+
+                        "A termination point can terminate a link.
+                        Depending on the type of topology, a termination point could,
+                        for example, refer to a port or an interface.";
+                    key "tp-id";
+                    uses tp-attributes;
+                }
+            }
+
+            list link {
+                description "
+                    A Network Link connects a by Local (Source) node and
+                    a Remote (Destination) Network Nodes via a set of the
+                    nodes' termination points.
+                    As it is possible to have several links between the same
+                    source and destination nodes, and as a link could potentially
+                    be re-homed between termination points, to ensure that we
+                    would always know to distinguish between links, every link
+                    is identified by a dedicated link identifier.
+                    Note that a link models a point-to-point link, not a multipoint
+                    link.
+                    Layering dependencies on links in underlay topologies are
+                    not represented as the layering information of nodes and of
+                    termination points is sufficient.
+                ";
+                key "link-id";
+                uses link-attributes;
+                must "boolean(../underlay-topology/link[./supporting-link]";
+                    // Constraint: any supporting link must be part of an underlay topology
+                must "boolean(../node[./source/source-node])";
+                    // Constraint: A link must have as source a node of the same topology
+                must "boolean(../node[./destination/dest-node])";
+                    // Constraint: A link must have as source a destination of the same topology
+                must "boolean(../node/termination-point[./source/source-tp])";
+                    // Constraint: The source termination point must be contained in the source node
+                must "boolean(../node/termination-point[./destination/dest-tp])";
+                    // Constraint: The destination termination point must be contained
+                    // in the destination node
+            }
+        }
+    }
+}