Add restconf-wadl-generator 05/96605/3
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 23 Jun 2021 11:49:44 +0000 (13:49 +0200)
committerRobert Varga <nite@hq.sk>
Wed, 23 Jun 2021 12:40:27 +0000 (12:40 +0000)
WADL generator is a tiny bit coming from MD-SAL's
maven-sal-api-gen-plugin, but dependent on RESTCONF semantics.

This patch imports its state as of commit
123a8fe79fa859b5e64e3efbd004d0730e25164d, taking ownership of it.

JIRA: MDSAL-232
Change-Id: I81cc5cb6e2ef3496605e3532087688eb4ab172e2
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
13 files changed:
artifacts/pom.xml
restconf/pom.xml
restconf/wadl-generator/pom.xml [new file with mode: 0644]
restconf/wadl-generator/src/main/java/org/opendaylight/netconf/restconf/wadl/generator/WadlGenerator.java [new file with mode: 0644]
restconf/wadl-generator/src/main/java/org/opendaylight/netconf/restconf/wadl/generator/WadlGeneratorFactory.java [new file with mode: 0644]
restconf/wadl-generator/src/main/java/org/opendaylight/netconf/restconf/wadl/generator/WadlTemplate.xtend [new file with mode: 0644]
restconf/wadl-generator/src/test/java/org/opendaylight/netconf/restconf/wadl/generator/WadlGenTest.java [new file with mode: 0644]
restconf/wadl-generator/src/test/resources/wadl-gen/controller-network-rpcs.yang [new file with mode: 0644]
restconf/wadl-generator/src/test/resources/wadl-gen/controller-network.yang [new file with mode: 0644]
restconf/wadl-generator/src/test/resources/wadl-gen/controller-openflow.yang [new file with mode: 0644]
restconf/wadl-generator/src/test/resources/wadl-gen/demo-topology.yang [new file with mode: 0644]
restconf/wadl-generator/src/test/resources/wadl-gen/ietf-inet-types@2010-09-24.yang [new file with mode: 0644]
restconf/wadl-generator/src/test/resources/wadl-gen/ietf-yang-types@2010-09-24.yang [new file with mode: 0644]

index 10d9327b3542d606504fbf9accb275c291aa4e9f..3a1adc3df6fc0802e421907dccdcb892be4db162 100644 (file)
                 <artifactId>websocket-client</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>restconf-wadl-generator</artifactId>
+                <version>${project.version}</version>
+            </dependency>
 
             <!-- restconf features -->
             <dependency>
index 254ae20e65eca665376a9490f4a4af5139e1e358..d35762429acb501fc892a31261f5f28e5c8818a4 100644 (file)
@@ -36,6 +36,7 @@
         <module>sal-rest-connector-config</module>
         <module>sal-rest-docgen</module>
         <module>sal-rest-docgen-maven</module>
+        <module>wadl-generator</module>
         <module>websocket-client</module>
         <!--
         FIXME: Needs to be reimplemented to not use YANGTools restconf impl
diff --git a/restconf/wadl-generator/pom.xml b/restconf/wadl-generator/pom.xml
new file mode 100644 (file)
index 0000000..636e3ee
--- /dev/null
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.netconf</groupId>
+        <artifactId>netconf-parent</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+        <relativePath>../../parent</relativePath>
+    </parent>
+
+    <artifactId>restconf-wadl-generator</artifactId>
+    <packaging>jar</packaging>
+    <description>A simple generator for WADL files, pluggable into yang-maven-plugin</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.xtext</groupId>
+            <artifactId>org.eclipse.xtext.xbase.lib</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.kohsuke.metainf-services</groupId>
+            <artifactId>metainf-services</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-model-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>plugin-generator-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-test-util</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.eclipse.xtend</groupId>
+                <artifactId>xtend-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/restconf/wadl-generator/src/main/java/org/opendaylight/netconf/restconf/wadl/generator/WadlGenerator.java b/restconf/wadl-generator/src/main/java/org/opendaylight/netconf/restconf/wadl/generator/WadlGenerator.java
new file mode 100644 (file)
index 0000000..63cc000
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.restconf.wadl.generator;
+
+import com.google.common.collect.ImmutableTable;
+import com.google.common.collect.Table;
+import java.util.Set;
+import org.opendaylight.yangtools.plugin.generator.api.FileGenerator;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFile;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFileLifecycle;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFilePath;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFileType;
+import org.opendaylight.yangtools.plugin.generator.api.ModuleResourceResolver;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.model.api.Module;
+
+final class WadlGenerator implements FileGenerator {
+    @Override
+    public Table<GeneratedFileType, GeneratedFilePath, GeneratedFile> generateFiles(final EffectiveModelContext context,
+            final Set<Module> localModules, final ModuleResourceResolver moduleResourcePathResolver) {
+        final var result = ImmutableTable.<GeneratedFileType, GeneratedFilePath, GeneratedFile>builder();
+
+        for (Module module : localModules) {
+            final CharSequence body = new WadlTemplate(context, module).body();
+            if (body != null) {
+                result.put(GeneratedFileType.RESOURCE, GeneratedFilePath.ofPath(module.getName() + ".wadl"),
+                    GeneratedFile.of(GeneratedFileLifecycle.TRANSIENT, body));
+            }
+        }
+        return result.build();
+    }
+}
diff --git a/restconf/wadl-generator/src/main/java/org/opendaylight/netconf/restconf/wadl/generator/WadlGeneratorFactory.java b/restconf/wadl-generator/src/main/java/org/opendaylight/netconf/restconf/wadl/generator/WadlGeneratorFactory.java
new file mode 100644 (file)
index 0000000..f64dfc8
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.restconf.wadl.generator;
+
+import java.util.Map;
+import org.kohsuke.MetaInfServices;
+import org.opendaylight.yangtools.plugin.generator.api.AbstractFileGeneratorFactory;
+import org.opendaylight.yangtools.plugin.generator.api.FileGenerator;
+import org.opendaylight.yangtools.plugin.generator.api.FileGeneratorFactory;
+
+@MetaInfServices(value = FileGeneratorFactory.class)
+public final class WadlGeneratorFactory extends AbstractFileGeneratorFactory {
+    public WadlGeneratorFactory() {
+        super(WadlGenerator.class.getName());
+    }
+
+    @Override
+    public FileGenerator newFileGenerator(final Map<String, String> configuration) {
+        return new WadlGenerator();
+    }
+}
diff --git a/restconf/wadl-generator/src/main/java/org/opendaylight/netconf/restconf/wadl/generator/WadlTemplate.xtend b/restconf/wadl-generator/src/main/java/org/opendaylight/netconf/restconf/wadl/generator/WadlTemplate.xtend
new file mode 100644 (file)
index 0000000..962df1e
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2021 PANTHEON.tech, s.r.o.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.restconf.wadl.generator
+
+import static java.util.Objects.requireNonNull
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import java.util.ArrayList
+import java.util.List
+import org.opendaylight.yangtools.yang.common.XMLNamespace
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
+import org.opendaylight.yangtools.yang.model.api.Module
+
+final class WadlTemplate {
+    static val PATH_DELIMETER = '/'
+
+    val EffectiveModelContext context
+    val Module module
+    val List<DataSchemaNode> configData = new ArrayList
+    val List<DataSchemaNode> operationalData = new ArrayList
+
+    var List<LeafSchemaNode> pathListParams
+
+    new(EffectiveModelContext context, Module module) {
+        this.context = requireNonNull(context)
+        this.module = requireNonNull(module)
+
+        for (child : module.childNodes) {
+            if (child instanceof ContainerSchemaNode || child instanceof ListSchemaNode) {
+                if (child.configuration) {
+                    configData.add(child)
+                } else {
+                    operationalData.add(child)
+                }
+            }
+        }
+    }
+
+    def body() {
+        if (!module.rpcs.empty || !configData.empty || !operationalData.empty) {
+            return application()
+        }
+        return null
+    }
+
+    private def application() '''
+        <?xml version="1.0"?>
+        <application xmlns="http://wadl.dev.java.net/2009/02" «module.importsAsNamespaces» xmlns:«module.prefix»="«module.namespace»">
+
+            <grammars>
+                <include href="«module.name».yang"/>
+                «FOR imprt : module.imports»
+                    <include href="«imprt.moduleName».yang"/>
+                «ENDFOR»
+            </grammars>
+
+            <resources base="http://localhost:9998/restconf">
+                «IF !operationalData.nullOrEmpty»
+                <resource path="operational">
+                    «FOR schemaNode : operationalData»
+                        «schemaNode.firstResource(false)»
+                    «ENDFOR»
+                </resource>
+                «ENDIF»
+                «IF !configData.nullOrEmpty»
+                <resource path="config">
+                    «FOR schemaNode : configData»
+                        «schemaNode.mehodPost»
+                    «ENDFOR»
+                    «FOR schemaNode : configData»
+                        «schemaNode.firstResource(true)»
+                    «ENDFOR»
+                </resource>
+                «ENDIF»
+                «IF !module.rpcs.nullOrEmpty»
+                <resource path="operations">
+                    «FOR rpc : module.rpcs»
+                        <resource path="«module.name»:«rpc.QName.localName»">
+                            «methodPostRpc(rpc.input !== null, rpc.output !== null)»
+                        </resource>
+                    «ENDFOR»
+                </resource>
+                «ENDIF»
+            </resources>
+        </application>
+    '''
+
+    private def importsAsNamespaces(Module module) '''
+        «FOR imprt : module.imports»
+            xmlns:«imprt.prefix»="«context.findModule(imprt.moduleName, imprt.revision).get.namespace»"
+        «ENDFOR»
+    '''
+
+    private def String firstResource(DataSchemaNode schemaNode, boolean config) '''
+        <resource path="«module.name»:«schemaNode.createPath»">
+            «resourceBody(schemaNode, config)»
+        </resource>
+    '''
+
+    private def String resource(DataSchemaNode schemaNode, boolean config) '''
+        <resource path="«schemaNode.createPath»">
+            «resourceBody(schemaNode, config)»
+        </resource>
+    '''
+
+    private def String createPath(DataSchemaNode schemaNode) {
+        pathListParams = new ArrayList
+        var StringBuilder path = new StringBuilder
+        path.append(schemaNode.QName.localName)
+        if (schemaNode instanceof ListSchemaNode) {
+            for (listKey : schemaNode.keyDefinition) {
+                pathListParams.add((schemaNode as DataNodeContainer).getDataChildByName(listKey) as LeafSchemaNode)
+                path.append(PATH_DELIMETER).append('{').append(listKey.localName).append('}')
+            }
+        }
+        return path.toString
+    }
+
+    private def String resourceBody(DataSchemaNode schemaNode, boolean config) '''
+        «IF !pathListParams.nullOrEmpty»
+            «resourceParams»
+        «ENDIF»
+        «schemaNode.methodGet»
+        «val children = (schemaNode as DataNodeContainer).childNodes.filter[it|it.listOrContainer]»
+        «IF config»
+            «schemaNode.methodDelete»
+            «schemaNode.methodPut»
+            «FOR child : children»
+                «child.mehodPost»
+            «ENDFOR»
+        «ENDIF»
+        «FOR child : children»
+            «child.resource(config)»
+        «ENDFOR»
+    '''
+
+    private def resourceParams() '''
+        «FOR pathParam : pathListParams»
+            «IF pathParam !== null»
+            «val type = pathParam.type.QName.localName»
+            <param required="true" style="template" name="«pathParam.QName.localName»" type="«type»"/>
+            «ENDIF»
+        «ENDFOR»
+    '''
+
+    private static def methodGet(DataSchemaNode schemaNode) '''
+        <method name="GET">
+            <response>
+                «representation(schemaNode.QName.namespace, schemaNode.QName.localName)»
+            </response>
+        </method>
+    '''
+
+    private static def methodPut(DataSchemaNode schemaNode) '''
+        <method name="PUT">
+            <request>
+                «representation(schemaNode.QName.namespace, schemaNode.QName.localName)»
+            </request>
+        </method>
+    '''
+
+    private static def mehodPost(DataSchemaNode schemaNode) '''
+        <method name="POST">
+            <request>
+                «representation(schemaNode.QName.namespace, schemaNode.QName.localName)»
+            </request>
+        </method>
+    '''
+
+    private static def methodPostRpc(boolean input, boolean output) '''
+        <method name="POST">
+            «IF input»
+            <request>
+                «representation(null, "input")»
+            </request>
+            «ENDIF»
+            «IF output»
+            <response>
+                «representation(null, "output")»
+            </response>
+            «ENDIF»
+        </method>
+    '''
+
+    private static def methodDelete(DataSchemaNode schemaNode) '''
+        <method name="DELETE" />
+    '''
+
+    private static def representation(XMLNamespace prefix, String name) '''
+        «val elementData = name»
+        <representation mediaType="application/xml" element="«elementData»"/>
+        <representation mediaType="text/xml" element="«elementData»"/>
+        <representation mediaType="application/json" element="«elementData»"/>
+        <representation mediaType="application/yang.data+xml" element="«elementData»"/>
+        <representation mediaType="application/yang.data+json" element="«elementData»"/>
+    '''
+
+    @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
+                justification = "https://github.com/spotbugs/spotbugs/issues/811")
+    private static def boolean isListOrContainer(DataSchemaNode schemaNode) {
+        return schemaNode instanceof ListSchemaNode || schemaNode instanceof ContainerSchemaNode
+    }
+}
diff --git a/restconf/wadl-generator/src/test/java/org/opendaylight/netconf/restconf/wadl/generator/WadlGenTest.java b/restconf/wadl-generator/src/test/java/org/opendaylight/netconf/restconf/wadl/generator/WadlGenTest.java
new file mode 100644 (file)
index 0000000..733baf0
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.restconf.wadl.generator;
+
+import static org.junit.Assert.assertEquals;
+
+import com.google.common.collect.Table;
+import java.util.Optional;
+import java.util.Set;
+import org.junit.Test;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFile;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFilePath;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFileType;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
+
+public class WadlGenTest {
+    @Test
+    public void testListGeneration() {
+        final WadlGenerator generator = new WadlGenerator();
+        final EffectiveModelContext context = YangParserTestUtils.parseYangResourceDirectory("/wadl-gen");
+        Table<GeneratedFileType, GeneratedFilePath, GeneratedFile> generatedWadlFiles = generator.generateFiles(context,
+            Set.copyOf(context.getModules()), (module, representation) -> Optional.empty());
+        assertEquals(3, generatedWadlFiles.size());
+        // TODO: more asserts
+    }
+}
diff --git a/restconf/wadl-generator/src/test/resources/wadl-gen/controller-network-rpcs.yang b/restconf/wadl-generator/src/test/resources/wadl-gen/controller-network-rpcs.yang
new file mode 100644 (file)
index 0000000..fd51039
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+module controller-network-rpcs {
+       yang-version 1;
+       namespace "urn:opendaylight:controller:network:rpcs";
+       prefix "topos";
+
+       import ietf-inet-types { prefix "inet"; }
+
+       revision 2013-05-20 {
+          description "Initial demo";
+       }
+
+       rpc activate-software-image {
+         input {
+             leaf image-name {
+                 type string;
+             }
+         }
+         output {
+             leaf status {
+                 type string;
+             }
+         }
+     }
+
+     rpc rock-the-house {
+         input {
+             leaf zip-code {
+                 type string;
+             }
+         }
+     }
+}
diff --git a/restconf/wadl-generator/src/test/resources/wadl-gen/controller-network.yang b/restconf/wadl-generator/src/test/resources/wadl-gen/controller-network.yang
new file mode 100644 (file)
index 0000000..b7499d4
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+module controller-network {
+       yang-version 1;
+       namespace "urn:opendaylight:controller:network";
+       prefix "topos";
+
+       import ietf-inet-types { prefix "inet"; }
+
+       revision 2013-05-20 {
+          description "Initial demo";
+       }
+
+
+
+
+       typedef topology-id {
+               type string;
+       }
+
+       typedef node-id {
+               type string;
+       }
+
+       typedef link-id {
+               type string;
+       }
+
+       typedef tp-id {
+               type string;
+               description "identifier for termination points on a port";
+       }
+
+       typedef tp-ref {
+               type leafref {
+                       path "/network/topologies/topology/nodes/node/termination-points/termination-point/tp-id";
+               }
+       }
+       typedef topology-ref {
+               type leafref {
+                       path "/network/topologies/topology/topology-id";
+               }
+               description "This type is used for leafs that reference topology identifier instance.";
+               // currently not used
+       }
+
+       typedef node-ref {
+               type leafref {
+                       path "/network/topologies/topology/nodes/node/node-id";
+               }
+               description "This type is used for leafs that reference a node instance.";
+       }
+
+       typedef link-ref {
+               type leafref {
+                       path "/network/topologies/topology/links/link/link-id";
+               }
+               description "This type is used for leafs that reference a link instance.";
+               // currently not used
+       }
+
+       typedef network-element-ref {
+               type leafref {
+                       path "/network/network-elements/network-element/element-id";
+               }
+       }
+
+
+       typedef element-id {
+               type string;
+       }
+
+       container network {
+               container topologies {
+                       list topology {
+                               description "
+                                       This is the model of abstract topology which contains only Network
+                                       Nodes and Network Links. Each topology MUST be identified by
+                                       unique topology-id for reason that the store could contain many
+                                       topologies.
+                               ";
+                               key "topology-id";
+                               leaf topology-id {
+                                       type topology-id;
+                                       description "
+                                               It is presumed that datastore will contain many topologies. To
+                                               distinguish between topologies it is vital to have UNIQUE
+                                               topology identifier.
+                                       ";
+                               }
+
+                               container types {
+                                       description "
+                                               The container for definition of topology types.
+                                               The augmenting modules should add empty optional leaf
+                                               to this container to signalize topology type.
+                                       ";
+                               }
+
+                               container nodes {
+                                       list node {
+                                               description "The list of network nodes defined for topology.";
+
+                                               key "node-id";
+                                               leaf node-id {
+                                                       type node-id;
+                                                       description "The Topology identifier of network-node.";
+                                               }
+
+                                               leaf supporting-ne {
+                                                       type network-element-ref;
+                                               }
+
+                                               container termination-points {
+                                                       list termination-point {
+                                                               key "tp-id";
+                                                               leaf tp-id {
+                                                                       type tp-id;
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               container links {
+                                       list link {
+                                               description "
+                                                       The Network Link which is defined by Local (Source) and
+                                                       Remote (Destination) Network Nodes. Every link MUST be
+                                                       defined either by identifier and his local and remote
+                                                       Network Nodes (in real applications it is common that many
+                                                       links are originated from one node and end up in same
+                                                       remote node). To ensure that we would always know to
+                                                       distinguish between links, every link SHOULD have
+                                                       identifier.
+                                               ";
+                                               key "link-id";
+
+                                               leaf link-id {
+                                                       type link-id;
+                                               }
+                                               container source {
+                                                       leaf source-node {
+                                                               type node-ref;
+                                                               description "Source node identifier.";
+                                                       }
+                                                       leaf source-tp {
+                                                               type tp-ref;
+                                                       }
+                                               }
+                                               container destination {
+                                                       leaf dest-node {
+                                                               type node-ref;
+                                                               description "Destination node identifier.";
+                                                       }
+                                                       leaf dest-tp {
+                                                               type tp-ref;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+               container network-elements {
+                       config true;
+                       list network-element {
+                               key "element-id";
+                               leaf element-id {
+                                       type element-id;
+                               }
+                       }
+               }
+       }
+
+       rpc activate-software-image {
+         input {
+             leaf image-name {
+                 type string;
+             }
+         }
+         output {
+             leaf status {
+                 type string;
+             }
+         }
+     }
+
+     rpc rock-the-house {
+         input {
+             leaf zip-code {
+                 type string;
+             }
+         }
+     }
+}
diff --git a/restconf/wadl-generator/src/test/resources/wadl-gen/controller-openflow.yang b/restconf/wadl-generator/src/test/resources/wadl-gen/controller-openflow.yang
new file mode 100644 (file)
index 0000000..dd9b30e
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+module controller-openflow {
+
+    namespace "urn:opendaylight:controller:openflow";
+    prefix "of";
+    import controller-network {prefix cn;}
+
+
+    revision 2013-05-20 {
+       description "Initial demo";
+    }
+
+
+
+
+
+    typedef datapath-id {
+        type string {
+            length 16;
+        }
+    }
+
+
+    augment "/cn:network/cn:topologies/cn:topology/cn:types" {
+        leaf openflow {type string;}
+    }
+
+    augment "/cn:network/cn:topologies/cn:topology/cn:links/cn:link/cn:source" {
+        when "../../../cn:types/of:openflow";
+
+        leaf logical-port {
+            type int32;
+        }
+    }
+
+    augment "/cn:network/cn:topologies/cn:topology/cn:links/cn:link/cn:destination" {
+        when "../../../cn:types/of:openflow";
+
+        leaf logical-port {
+            type int32;
+        }
+    }
+
+    augment "/cn:network/cn:topologies/cn:topology/cn:nodes/cn:node" {
+        when "../../../cn:types/of:openflow";
+        leaf datapath-id {
+            type datapath-id;
+        }
+    }
+
+    augment "/cn:network/cn:network-elements/cn:network-element" {
+        leaf datapath-id {
+            type datapath-id;
+        }
+
+        container ports {
+            list port {
+                key "logical-port-id";
+
+                leaf logical-port-id {
+                    type int32;
+                }
+
+                // Should be replaced with ref to interface
+                leaf physical-name {
+                    type string;
+                }
+            }
+        }
+        container flow-tables {
+            list flow-table {
+                key "flow-table-id";
+                leaf flow-table-id {
+                    type string;
+                }
+
+            }
+        }
+    }
+}
diff --git a/restconf/wadl-generator/src/test/resources/wadl-gen/demo-topology.yang b/restconf/wadl-generator/src/test/resources/wadl-gen/demo-topology.yang
new file mode 100644 (file)
index 0000000..79045b8
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+module demo-topology {
+       yang-version 1;
+    namespace "urn:model.1demo-275topology.4.5.my";
+    prefix "tp";
+
+    organization "OPEN DAYLIGHT";
+    contact "http://www.opendaylight.org/";
+
+    description "
+               This module contains the definitions of elements that creates network
+               topology i.e. definition of network nodes and links. This module is
+               not designed to be used solely for network representation. This module
+               SHOULD be used as base module in defining the network topology.
+       ";
+
+    revision "2013-02-08"{
+               reference " WILL BE DEFINED LATER";
+       }
+
+       container topology {
+        description "
+                       This is the model of abstract topology which contains only Network
+                       Nodes and Network Links. Each topology MUST be identified by
+                       unique topology-id for reason that the store could contain many
+                       topologies.
+               ";
+
+        leaf topology-id {
+            type string;
+            description "
+                               It is presumed that datastore will contain many topologies. To
+                               distinguish between topologies it is vital to have UNIQUE
+                               topology identifier.
+                       ";
+        }
+
+        container network-nodes {
+               list network-node {
+                   description "The list of network nodes defined for topology.";
+
+                       key "node-id";
+
+                       leaf node-id {
+                               type string;
+                               description "The Topology identifier of network-node.";
+                       }
+
+                list network-interface {
+                    key "interface-id";
+
+                    leaf interface-id {
+                        type uint8;
+                    }
+
+                    leaf interface-address {
+                        type string;
+                    }
+                }
+
+                   container node-attributes {
+                                       description "
+                                               Additional attributes that can Network Node contains.
+                                       ";
+
+                                       leaf geo-latitude {
+                                               type decimal64 {
+                                                       fraction-digits 2;
+                                               }
+                                               config true;
+                                       }
+
+                                       leaf geo-longitude {
+                                               type decimal64 {
+                                                       fraction-digits 2;
+                                               }
+                                               config true;
+                                       }
+                               }
+               }
+        }
+
+        container network-links {
+               list network-link {
+                   description "
+                                       The Network Link which is defined by Local (Source) and
+                                       Remote (Destination) Network Nodes. Every link MUST be
+                                       defined either by identifier and his local and remote
+                                       Network Nodes (in real applications it is common that many
+                                       links are originated from one node and end up in same
+                                       remote node). To ensure that we would always know to
+                                       distinguish between links, every link SHOULD have
+                                       identifier.
+                               ";
+                       key "link-id";
+
+                       leaf link-id {
+                               type string;
+                               description "";
+                       }
+
+                   container source {
+                                       leaf node-id {
+                                               type string;
+                                               description "Source node identifier.";
+                                       }
+                               }
+
+                               container destination {
+                                       leaf node-id {
+                                               type string;
+                                               description "Destination node identifier.";
+                                       }
+                               }
+
+                               container link-attributes {
+                                       description "Aditional attributes that can Network Link contains.";
+                               }
+                   }
+        }
+    }
+}
diff --git a/restconf/wadl-generator/src/test/resources/wadl-gen/ietf-inet-types@2010-09-24.yang b/restconf/wadl-generator/src/test/resources/wadl-gen/ietf-inet-types@2010-09-24.yang
new file mode 100644 (file)
index 0000000..de20feb
--- /dev/null
@@ -0,0 +1,418 @@
+ module ietf-inet-types {
+
+   namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types";
+   prefix "inet";
+
+   organization
+    "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+   contact
+    "WG Web:   <http://tools.ietf.org/wg/netmod/>
+     WG List:  <mailto:netmod@ietf.org>
+
+     WG Chair: David Partain
+               <mailto:david.partain@ericsson.com>
+
+     WG Chair: David Kessens
+               <mailto:david.kessens@nsn.com>
+
+     Editor:   Juergen Schoenwaelder
+               <mailto:j.schoenwaelder@jacobs-university.de>";
+
+   description
+    "This module contains a collection of generally useful derived
+     YANG data types for Internet addresses and related things.
+
+     Copyright (c) 2010 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or without
+     modification, is permitted pursuant to, and subject to the license
+     terms contained in, the Simplified BSD License set forth in Section
+     4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 6021; see
+     the RFC itself for full legal notices.";
+
+   revision 2010-09-24 {
+     description
+      "Initial revision.";
+     reference
+      "RFC 6021: Common YANG Data Types";
+   }
+
+   /*** collection of protocol field related types ***/
+
+   typedef ip-version {
+     type enumeration {
+       enum unknown {
+         value "0";
+         description
+          "An unknown or unspecified version of the Internet protocol.";
+       }
+       enum ipv4 {
+         value "1";
+         description
+          "The IPv4 protocol as defined in RFC 791.";
+       }
+       enum ipv6 {
+         value "2";
+         description
+          "The IPv6 protocol as defined in RFC 2460.";
+       }
+     }
+     description
+      "This value represents the version of the IP protocol.
+
+       In the value set and its semantics, this type is equivalent
+       to the InetVersion textual convention of the SMIv2.";
+     reference
+      "RFC  791: Internet Protocol
+       RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
+       RFC 4001: Textual Conventions for Internet Network Addresses";
+   }
+
+   typedef dscp {
+     type uint8 {
+       range "0..63";
+     }
+     description
+      "The dscp type represents a Differentiated Services Code-Point
+       that may be used for marking packets in a traffic stream.
+
+       In the value set and its semantics, this type is equivalent
+       to the Dscp textual convention of the SMIv2.";
+     reference
+      "RFC 3289: Management Information Base for the Differentiated
+                 Services Architecture
+       RFC 2474: Definition of the Differentiated Services Field
+                 (DS Field) in the IPv4 and IPv6 Headers
+       RFC 2780: IANA Allocation Guidelines For Values In
+                 the Internet Protocol and Related Headers";
+   }
+
+   typedef ipv6-flow-label {
+     type uint32 {
+       range "0..1048575";
+     }
+     description
+      "The flow-label type represents flow identifier or Flow Label
+       in an IPv6 packet header that may be used to discriminate
+       traffic flows.
+
+       In the value set and its semantics, this type is equivalent
+       to the IPv6FlowLabel textual convention of the SMIv2.";
+     reference
+      "RFC 3595: Textual Conventions for IPv6 Flow Label
+       RFC 2460: Internet Protocol, Version 6 (IPv6) Specification";
+   }
+
+   typedef port-number {
+     type uint16 {
+       range "0..65535";
+     }
+     description
+      "The port-number type represents a 16-bit port number of an
+       Internet transport layer protocol such as UDP, TCP, DCCP, or
+       SCTP.  Port numbers are assigned by IANA.  A current list of
+       all assignments is available from <http://www.iana.org/>.
+
+       Note that the port number value zero is reserved by IANA.  In
+       situations where the value zero does not make sense, it can
+       be excluded by subtyping the port-number type.
+
+       In the value set and its semantics, this type is equivalent
+       to the InetPortNumber textual convention of the SMIv2.";
+     reference
+      "RFC  768: User Datagram Protocol
+       RFC  793: Transmission Control Protocol
+       RFC 4960: Stream Control Transmission Protocol
+       RFC 4340: Datagram Congestion Control Protocol (DCCP)
+       RFC 4001: Textual Conventions for Internet Network Addresses";
+   }
+
+   /*** collection of autonomous system related types ***/
+
+   typedef as-number {
+     type uint32;
+     description
+      "The as-number type represents autonomous system numbers
+       which identify an Autonomous System (AS).  An AS is a set
+       of routers under a single technical administration, using
+       an interior gateway protocol and common metrics to route
+       packets within the AS, and using an exterior gateway
+       protocol to route packets to other ASs'.  IANA maintains
+       the AS number space and has delegated large parts to the
+       regional registries.
+
+       Autonomous system numbers were originally limited to 16
+       bits.  BGP extensions have enlarged the autonomous system
+       number space to 32 bits.  This type therefore uses an uint32
+       base type without a range restriction in order to support
+       a larger autonomous system number space.
+
+       In the value set and its semantics, this type is equivalent
+       to the InetAutonomousSystemNumber textual convention of
+       the SMIv2.";
+     reference
+      "RFC 1930: Guidelines for creation, selection, and registration
+                 of an Autonomous System (AS)
+       RFC 4271: A Border Gateway Protocol 4 (BGP-4)
+       RFC 4893: BGP Support for Four-octet AS Number Space
+       RFC 4001: Textual Conventions for Internet Network Addresses";
+   }
+
+   /*** collection of IP address and hostname related types ***/
+
+   typedef ip-address {
+     type union {
+       type inet:ipv4-address;
+       type inet:ipv6-address;
+     }
+     description
+      "The ip-address type represents an IP address and is IP
+       version neutral.  The format of the textual representations
+       implies the IP version.";
+   }
+
+   typedef ipv4-address {
+     type string {
+       pattern
+         '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+       +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+       + '(%[\p{N}\p{L}]+)?';
+     }
+     description
+       "The ipv4-address type represents an IPv4 address in
+        dotted-quad notation.  The IPv4 address may include a zone
+        index, separated by a % sign.
+
+        The zone index is used to disambiguate identical address
+        values.  For link-local addresses, the zone index will
+        typically be the interface index number or the name of an
+        interface.  If the zone index is not present, the default
+        zone of the device will be used.
+
+        The canonical format for the zone index is the numerical
+        format";
+   }
+
+   typedef ipv6-address {
+     type string {
+       pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+             + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+             + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+             + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+             + '(%[\p{N}\p{L}]+)?';
+       pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+             + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+             + '(%.+)?';
+     }
+     description
+      "The ipv6-address type represents an IPv6 address in full,
+       mixed, shortened, and shortened-mixed notation.  The IPv6
+       address may include a zone index, separated by a % sign.
+
+       The zone index is used to disambiguate identical address
+       values.  For link-local addresses, the zone index will
+       typically be the interface index number or the name of an
+       interface.  If the zone index is not present, the default
+       zone of the device will be used.
+
+       The canonical format of IPv6 addresses uses the compressed
+       format described in RFC 4291, Section 2.2, item 2 with the
+       following additional rules: the :: substitution must be
+       applied to the longest sequence of all-zero 16-bit chunks
+       in an IPv6 address.  If there is a tie, the first sequence
+       of all-zero 16-bit chunks is replaced by ::.  Single
+       all-zero 16-bit chunks are not compressed.  The canonical
+       format uses lowercase characters and leading zeros are
+       not allowed.  The canonical format for the zone index is
+       the numerical format as described in RFC 4007, Section
+       11.2.";
+     reference
+      "RFC 4291: IP Version 6 Addressing Architecture
+       RFC 4007: IPv6 Scoped Address Architecture
+       RFC 5952: A Recommendation for IPv6 Address Text Representation";
+   }
+
+   typedef ip-prefix {
+     type union {
+       type inet:ipv4-prefix;
+       type inet:ipv6-prefix;
+     }
+     description
+      "The ip-prefix type represents an IP prefix and is IP
+       version neutral.  The format of the textual representations
+       implies the IP version.";
+   }
+
+   typedef ipv4-prefix {
+     type string {
+       pattern
+          '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+        +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+        + '/(([0-9])|([1-2][0-9])|(3[0-2]))';
+     }
+     description
+      "The ipv4-prefix type represents an IPv4 address prefix.
+       The prefix length is given by the number following the
+       slash character and must be less than or equal to 32.
+
+       A prefix length value of n corresponds to an IP address
+       mask that has n contiguous 1-bits from the most
+       significant bit (MSB) and all other bits set to 0.
+
+       The canonical format of an IPv4 prefix has all bits of
+       the IPv4 address set to zero that are not part of the
+       IPv4 prefix.";
+   }
+
+   typedef ipv6-prefix {
+     type string {
+       pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+             + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+             + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+             + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+             + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))';
+       pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+             + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+             + '(/.+)';
+     }
+     description
+      "The ipv6-prefix type represents an IPv6 address prefix.
+       The prefix length is given by the number following the
+       slash character and must be less than or equal 128.
+
+       A prefix length value of n corresponds to an IP address
+       mask that has n contiguous 1-bits from the most
+       significant bit (MSB) and all other bits set to 0.
+
+       The IPv6 address should have all bits that do not belong
+       to the prefix set to zero.
+
+       The canonical format of an IPv6 prefix has all bits of
+       the IPv6 address set to zero that are not part of the
+       IPv6 prefix.  Furthermore, IPv6 address is represented
+       in the compressed format described in RFC 4291, Section
+       2.2, item 2 with the following additional rules: the ::
+       substitution must be applied to the longest sequence of
+       all-zero 16-bit chunks in an IPv6 address.  If there is
+       a tie, the first sequence of all-zero 16-bit chunks is
+       replaced by ::.  Single all-zero 16-bit chunks are not
+       compressed.  The canonical format uses lowercase
+       characters and leading zeros are not allowed.";
+     reference
+      "RFC 4291: IP Version 6 Addressing Architecture";
+   }
+
+   /*** collection of domain name and URI types ***/
+
+   typedef domain-name {
+     type string {
+       pattern '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
+            +  '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
+            +  '|\.';
+       length "1..253";
+     }
+     description
+      "The domain-name type represents a DNS domain name.  The
+       name SHOULD be fully qualified whenever possible.
+
+       Internet domain names are only loosely specified.  Section
+       3.5 of RFC 1034 recommends a syntax (modified in Section
+       2.1 of RFC 1123).  The pattern above is intended to allow
+       for current practice in domain name use, and some possible
+       future expansion.  It is designed to hold various types of
+       domain names, including names used for A or AAAA records
+       (host names) and other records, such as SRV records.  Note
+       that Internet host names have a stricter syntax (described
+       in RFC 952) than the DNS recommendations in RFCs 1034 and
+       1123, and that systems that want to store host names in
+       schema nodes using the domain-name type are recommended to
+       adhere to this stricter standard to ensure interoperability.
+
+       The encoding of DNS names in the DNS protocol is limited
+       to 255 characters.  Since the encoding consists of labels
+       prefixed by a length bytes and there is a trailing NULL
+       byte, only 253 characters can appear in the textual dotted
+       notation.
+
+       The description clause of schema nodes using the domain-name
+       type MUST describe when and how these names are resolved to
+       IP addresses.  Note that the resolution of a domain-name value
+       may require to query multiple DNS records (e.g., A for IPv4
+       and AAAA for IPv6).  The order of the resolution process and
+       which DNS record takes precedence can either be defined
+       explicitely or it may depend on the configuration of the
+       resolver.
+
+       Domain-name values use the US-ASCII encoding.  Their canonical
+       format uses lowercase US-ASCII characters.  Internationalized
+       domain names MUST be encoded in punycode as described in RFC
+       3492";
+     reference
+      "RFC  952: DoD Internet Host Table Specification
+       RFC 1034: Domain Names - Concepts and Facilities
+       RFC 1123: Requirements for Internet Hosts -- Application
+                 and Support
+       RFC 2782: A DNS RR for specifying the location of services
+                 (DNS SRV)
+       RFC 3492: Punycode: A Bootstring encoding of Unicode for
+                 Internationalized Domain Names in Applications
+                 (IDNA)
+       RFC 5891: Internationalizing Domain Names in Applications
+                 (IDNA): Protocol";
+   }
+
+   typedef host {
+     type union {
+       type inet:ip-address;
+       type inet:domain-name;
+     }
+     description
+      "The host type represents either an IP address or a DNS
+       domain name.";
+   }
+
+   typedef uri {
+     type string;
+     description
+      "The uri type represents a Uniform Resource Identifier
+       (URI) as defined by STD 66.
+
+       Objects using the uri type MUST be in US-ASCII encoding,
+       and MUST be normalized as described by RFC 3986 Sections
+       6.2.1, 6.2.2.1, and 6.2.2.2.  All unnecessary
+       percent-encoding is removed, and all case-insensitive
+       characters are set to lowercase except for hexadecimal
+       digits, which are normalized to uppercase as described in
+       Section 6.2.2.1.
+
+       The purpose of this normalization is to help provide
+       unique URIs.  Note that this normalization is not
+       sufficient to provide uniqueness.  Two URIs that are
+       textually distinct after this normalization may still be
+       equivalent.
+
+       Objects using the uri type may restrict the schemes that
+       they permit.  For example, 'data:' and 'urn:' schemes
+       might not be appropriate.
+
+       A zero-length URI is not a valid URI.  This can be used to
+       express 'URI absent' where required.
+
+       In the value set and its semantics, this type is equivalent
+       to the Uri SMIv2 textual convention defined in RFC 5017.";
+     reference
+      "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
+       RFC 3305: Report from the Joint W3C/IETF URI Planning Interest
+                 Group: Uniform Resource Identifiers (URIs), URLs,
+                 and Uniform Resource Names (URNs): Clarifications
+                 and Recommendations
+       RFC 5017: MIB Textual Conventions for Uniform Resource
+                 Identifiers (URIs)";
+   }
+
+ }
diff --git a/restconf/wadl-generator/src/test/resources/wadl-gen/ietf-yang-types@2010-09-24.yang b/restconf/wadl-generator/src/test/resources/wadl-gen/ietf-yang-types@2010-09-24.yang
new file mode 100644 (file)
index 0000000..51d9f8b
--- /dev/null
@@ -0,0 +1,396 @@
+ module ietf-yang-types {
+
+   namespace "urn:ietf:params:xml:ns:yang:ietf-yang-types";
+   prefix "yang";
+
+   organization
+    "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+   contact
+    "WG Web:   <http://tools.ietf.org/wg/netmod/>
+     WG List:  <mailto:netmod@ietf.org>
+
+     WG Chair: David Partain
+               <mailto:david.partain@ericsson.com>
+
+     WG Chair: David Kessens
+               <mailto:david.kessens@nsn.com>
+
+     Editor:   Juergen Schoenwaelder
+               <mailto:j.schoenwaelder@jacobs-university.de>";
+
+   description
+    "This module contains a collection of generally useful derived
+     YANG data types.
+
+     Copyright (c) 2010 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or without
+     modification, is permitted pursuant to, and subject to the license
+     terms contained in, the Simplified BSD License set forth in Section
+     4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 6021; see
+     the RFC itself for full legal notices.";
+
+   revision 2010-09-24 {
+     description
+      "Initial revision.";
+     reference
+      "RFC 6021: Common YANG Data Types";
+   }
+
+   /*** collection of counter and gauge types ***/
+
+   typedef counter32 {
+     type uint32;
+     description
+      "The counter32 type represents a non-negative integer
+       that monotonically increases until it reaches a
+       maximum value of 2^32-1 (4294967295 decimal), when it
+       wraps around and starts increasing again from zero.
+
+       Counters have no defined 'initial' value, and thus, a
+       single value of a counter has (in general) no information
+       content.  Discontinuities in the monotonically increasing
+       value normally occur at re-initialization of the
+       management system, and at other times as specified in the
+       description of a schema node using this type.  If such
+       other times can occur, for example, the creation of
+       a schema node of type counter32 at times other than
+       re-initialization, then a corresponding schema node
+       should be defined, with an appropriate type, to indicate
+       the last discontinuity.
+
+       The counter32 type should not be used for configuration
+       schema nodes.  A default statement SHOULD NOT be used in
+       combination with the type counter32.
+
+       In the value set and its semantics, this type is equivalent
+       to the Counter32 type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   typedef zero-based-counter32 {
+     type yang:counter32;
+     default "0";
+     description
+      "The zero-based-counter32 type represents a counter32
+       that has the defined 'initial' value zero.
+
+       A schema node of this type will be set to zero (0) on creation
+       and will thereafter increase monotonically until it reaches
+       a maximum value of 2^32-1 (4294967295 decimal), when it
+       wraps around and starts increasing again from zero.
+
+       Provided that an application discovers a new schema node
+       of this type within the minimum time to wrap, it can use the
+       'initial' value as a delta.  It is important for a management
+       station to be aware of this minimum time and the actual time
+       between polls, and to discard data if the actual time is too
+       long or there is no defined minimum time.
+
+       In the value set and its semantics, this type is equivalent
+       to the ZeroBasedCounter32 textual convention of the SMIv2.";
+     reference
+       "RFC 4502: Remote Network Monitoring Management Information
+                  Base Version 2";
+   }
+
+   typedef counter64 {
+     type uint64;
+     description
+      "The counter64 type represents a non-negative integer
+       that monotonically increases until it reaches a
+       maximum value of 2^64-1 (18446744073709551615 decimal),
+       when it wraps around and starts increasing again from zero.
+
+       Counters have no defined 'initial' value, and thus, a
+       single value of a counter has (in general) no information
+       content.  Discontinuities in the monotonically increasing
+       value normally occur at re-initialization of the
+       management system, and at other times as specified in the
+       description of a schema node using this type.  If such
+       other times can occur, for example, the creation of
+       a schema node of type counter64 at times other than
+       re-initialization, then a corresponding schema node
+       should be defined, with an appropriate type, to indicate
+       the last discontinuity.
+
+       The counter64 type should not be used for configuration
+       schema nodes.  A default statement SHOULD NOT be used in
+       combination with the type counter64.
+
+       In the value set and its semantics, this type is equivalent
+       to the Counter64 type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   typedef zero-based-counter64 {
+     type yang:counter64;
+     default "0";
+     description
+      "The zero-based-counter64 type represents a counter64 that
+       has the defined 'initial' value zero.
+
+       A schema node of this type will be set to zero (0) on creation
+       and will thereafter increase monotonically until it reaches
+       a maximum value of 2^64-1 (18446744073709551615 decimal),
+       when it wraps around and starts increasing again from zero.
+
+       Provided that an application discovers a new schema node
+       of this type within the minimum time to wrap, it can use the
+       'initial' value as a delta.  It is important for a management
+       station to be aware of this minimum time and the actual time
+       between polls, and to discard data if the actual time is too
+       long or there is no defined minimum time.
+
+       In the value set and its semantics, this type is equivalent
+       to the ZeroBasedCounter64 textual convention of the SMIv2.";
+     reference
+      "RFC 2856: Textual Conventions for Additional High Capacity
+                 Data Types";
+   }
+
+   typedef gauge32 {
+     type uint32;
+     description
+      "The gauge32 type represents a non-negative integer, which
+       may increase or decrease, but shall never exceed a maximum
+       value, nor fall below a minimum value.  The maximum value
+       cannot be greater than 2^32-1 (4294967295 decimal), and
+       the minimum value cannot be smaller than 0.  The value of
+       a gauge32 has its maximum value whenever the information
+       being modeled is greater than or equal to its maximum
+       value, and has its minimum value whenever the information
+       being modeled is smaller than or equal to its minimum value.
+       If the information being modeled subsequently decreases
+       below (increases above) the maximum (minimum) value, the
+       gauge32 also decreases (increases).
+
+       In the value set and its semantics, this type is equivalent
+       to the Gauge32 type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   typedef gauge64 {
+     type uint64;
+     description
+      "The gauge64 type represents a non-negative integer, which
+       may increase or decrease, but shall never exceed a maximum
+       value, nor fall below a minimum value.  The maximum value
+       cannot be greater than 2^64-1 (18446744073709551615), and
+       the minimum value cannot be smaller than 0.  The value of
+       a gauge64 has its maximum value whenever the information
+       being modeled is greater than or equal to its maximum
+       value, and has its minimum value whenever the information
+       being modeled is smaller than or equal to its minimum value.
+       If the information being modeled subsequently decreases
+       below (increases above) the maximum (minimum) value, the
+       gauge64 also decreases (increases).
+
+       In the value set and its semantics, this type is equivalent
+       to the CounterBasedGauge64 SMIv2 textual convention defined
+       in RFC 2856";
+     reference
+      "RFC 2856: Textual Conventions for Additional High Capacity
+                 Data Types";
+   }
+
+   /*** collection of identifier related types ***/
+
+   typedef object-identifier {
+     type string {
+       pattern '(([0-1](\.[1-3]?[0-9]))|(2\.(0|([1-9]\d*))))'
+             + '(\.(0|([1-9]\d*)))*';
+     }
+     description
+      "The object-identifier type represents administratively
+       assigned names in a registration-hierarchical-name tree.
+
+       Values of this type are denoted as a sequence of numerical
+       non-negative sub-identifier values.  Each sub-identifier
+       value MUST NOT exceed 2^32-1 (4294967295).  Sub-identifiers
+       are separated by single dots and without any intermediate
+       whitespace.
+
+       The ASN.1 standard restricts the value space of the first
+       sub-identifier to 0, 1, or 2.  Furthermore, the value space
+       of the second sub-identifier is restricted to the range
+       0 to 39 if the first sub-identifier is 0 or 1.  Finally,
+       the ASN.1 standard requires that an object identifier
+       has always at least two sub-identifier.  The pattern
+       captures these restrictions.
+
+       Although the number of sub-identifiers is not limited,
+       module designers should realize that there may be
+       implementations that stick with the SMIv2 limit of 128
+       sub-identifiers.
+
+       This type is a superset of the SMIv2 OBJECT IDENTIFIER type
+       since it is not restricted to 128 sub-identifiers.  Hence,
+       this type SHOULD NOT be used to represent the SMIv2 OBJECT
+       IDENTIFIER type, the object-identifier-128 type SHOULD be
+       used instead.";
+     reference
+      "ISO9834-1: Information technology -- Open Systems
+       Interconnection -- Procedures for the operation of OSI
+       Registration Authorities: General procedures and top
+       arcs of the ASN.1 Object Identifier tree";
+   }
+
+
+
+
+   typedef object-identifier-128 {
+     type object-identifier {
+       pattern '\d*(\.\d*){1,127}';
+     }
+     description
+      "This type represents object-identifiers restricted to 128
+       sub-identifiers.
+
+       In the value set and its semantics, this type is equivalent
+       to the OBJECT IDENTIFIER type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   /*** collection of date and time related types ***/
+
+   typedef date-and-time {
+     type string {
+       pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?'
+             + '(Z|[\+\-]\d{2}:\d{2})';
+     }
+     description
+      "The date-and-time type is a profile of the ISO 8601
+       standard for representation of dates and times using the
+       Gregorian calendar.  The profile is defined by the
+       date-time production in Section 5.6 of RFC 3339.
+
+       The date-and-time type is compatible with the dateTime XML
+       schema type with the following notable exceptions:
+
+       (a) The date-and-time type does not allow negative years.
+
+       (b) The date-and-time time-offset -00:00 indicates an unknown
+           time zone (see RFC 3339) while -00:00 and +00:00 and Z all
+           represent the same time zone in dateTime.
+
+       (c) The canonical format (see below) of data-and-time values
+           differs from the canonical format used by the dateTime XML
+           schema type, which requires all times to be in UTC using the
+           time-offset 'Z'.
+
+       This type is not equivalent to the DateAndTime textual
+       convention of the SMIv2 since RFC 3339 uses a different
+       separator between full-date and full-time and provides
+       higher resolution of time-secfrac.
+
+       The canonical format for date-and-time values with a known time
+       zone uses a numeric time zone offset that is calculated using
+       the device's configured known offset to UTC time.  A change of
+       the device's offset to UTC time will cause date-and-time values
+       to change accordingly.  Such changes might happen periodically
+       in case a server follows automatically daylight saving time
+       (DST) time zone offset changes.  The canonical format for
+       date-and-time values with an unknown time zone (usually referring
+       to the notion of local time) uses the time-offset -00:00.";
+     reference
+      "RFC 3339: Date and Time on the Internet: Timestamps
+       RFC 2579: Textual Conventions for SMIv2
+       XSD-TYPES: XML Schema Part 2: Datatypes Second Edition";
+   }
+
+   typedef timeticks {
+     type uint32;
+     description
+      "The timeticks type represents a non-negative integer that
+       represents the time, modulo 2^32 (4294967296 decimal), in
+       hundredths of a second between two epochs.  When a schema
+       node is defined that uses this type, the description of
+       the schema node identifies both of the reference epochs.
+
+       In the value set and its semantics, this type is equivalent
+       to the TimeTicks type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   typedef timestamp {
+     type yang:timeticks;
+     description
+      "The timestamp type represents the value of an associated
+       timeticks schema node at which a specific occurrence happened.
+       The specific occurrence must be defined in the description
+       of any schema node defined using this type.  When the specific
+       occurrence occurred prior to the last time the associated
+       timeticks attribute was zero, then the timestamp value is
+       zero.  Note that this requires all timestamp values to be
+       reset to zero when the value of the associated timeticks
+       attribute reaches 497+ days and wraps around to zero.
+
+       The associated timeticks schema node must be specified
+       in the description of any schema node using this type.
+
+       In the value set and its semantics, this type is equivalent
+       to the TimeStamp textual convention of the SMIv2.";
+     reference
+      "RFC 2579: Textual Conventions for SMIv2";
+   }
+
+   /*** collection of generic address types ***/
+
+   typedef phys-address {
+     type string {
+       pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?';
+     }
+     description
+      "Represents media- or physical-level addresses represented
+       as a sequence octets, each octet represented by two hexadecimal
+       numbers.  Octets are separated by colons.  The canonical
+       representation uses lowercase characters.
+
+       In the value set and its semantics, this type is equivalent
+       to the PhysAddress textual convention of the SMIv2.";
+     reference
+      "RFC 2579: Textual Conventions for SMIv2";
+   }
+
+   typedef mac-address {
+     type string {
+       pattern '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}';
+     }
+     description
+      "The mac-address type represents an IEEE 802 MAC address.
+       The canonical representation uses lowercase characters.
+
+       In the value set and its semantics, this type is equivalent
+       to the MacAddress textual convention of the SMIv2.";
+     reference
+      "IEEE 802: IEEE Standard for Local and Metropolitan Area
+                 Networks: Overview and Architecture
+       RFC 2579: Textual Conventions for SMIv2";
+   }
+
+   /*** collection of XML specific types ***/
+
+   typedef xpath1.0 {
+     type string;
+     description
+      "This type represents an XPATH 1.0 expression.
+
+       When a schema node is defined that uses this type, the
+       description of the schema node MUST specify the XPath
+       context in which the XPath expression is evaluated.";
+     reference
+      "XPATH: XML Path Language (XPath) Version 1.0";
+   }
+
+ }