Add support for RFC6536 extensions 41/65141/11
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 3 Nov 2017 22:05:10 +0000 (23:05 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 15 Nov 2017 11:32:29 +0000 (12:32 +0100)
This patch adds support for parsing RFC6536 extensions and related
concepts for end users.

Change-Id: I41ae3192b74660be409c63bbec82a1a14c7de4af
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
23 files changed:
common/artifacts/pom.xml
features/odl-yangtools-parser-api/pom.xml
features/odl-yangtools-parser/pom.xml
yang/pom.xml
yang/rfc6536-model-api/pom.xml [new file with mode: 0644]
yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/DefaultDenyAllEffectiveStatement.java [new file with mode: 0644]
yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/DefaultDenyAllSchemaNode.java [new file with mode: 0644]
yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/DefaultDenyAllStatement.java [new file with mode: 0644]
yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/DefaultDenyWriteEffectiveStatement.java [new file with mode: 0644]
yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/DefaultDenyWriteSchemaNode.java [new file with mode: 0644]
yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/DefaultDenyWriteStatement.java [new file with mode: 0644]
yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/NACMConstants.java [new file with mode: 0644]
yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/NACMStatements.java [new file with mode: 0644]
yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/package-info.java [new file with mode: 0644]
yang/rfc6536-parser-support/pom.xml [new file with mode: 0644]
yang/rfc6536-parser-support/src/main/java/org/opendaylight/yangtools/rfc6536/parser/DefaultDenyAllStatementSupport.java [new file with mode: 0644]
yang/rfc6536-parser-support/src/main/java/org/opendaylight/yangtools/rfc6536/parser/DefaultDenyWriteStatementSupport.java [new file with mode: 0644]
yang/rfc6536-parser-support/src/main/java/org/opendaylight/yangtools/rfc6536/parser/package-info.java [new file with mode: 0644]
yang/rfc6536-parser-support/src/test/java/org/opendaylight/yangtools/rfc6536/parser/NACMTest.java [new file with mode: 0644]
yang/rfc6536-parser-support/src/test/resources/ietf-netconf-acm@2012-02-22.yang [new file with mode: 0644]
yang/rfc6536-parser-support/src/test/resources/ietf-yang-types@2013-07-15.yang [new file with mode: 0644]
yang/yang-parser-impl/pom.xml
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/DefaultReactors.java

index 69f1405277ca5d260ef5b873f43291f088d4cff7..a48bccd88fe6f7e77a2700da595ce7a033f83189 100644 (file)
                 <version>2.0.0-SNAPSHOT</version>
             </dependency>
 
+            <dependency>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>rfc6536-model-api</artifactId>
+                <version>2.0.0-SNAPSHOT</version>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>rfc6536-parser-support</artifactId>
+                <version>2.0.0-SNAPSHOT</version>
+            </dependency>
+
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>rfc7952-model-api</artifactId>
index c51a780f474ea499e0d4452f06a5829c2ca9ae9b..41ce74bab8caf459c046f8428fc8251369c36df0 100644 (file)
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>openconfig-model-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>rfc6536-model-api</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>rfc7952-model-api</artifactId>
index d8c2d0989999b393ec9ba8cfdd6146bc94d1bfde..b87ed34a1072398be3f5a703ebee12068c687a70 100644 (file)
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>openconfig-parser-support</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>rfc6536-parser-support</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>rfc7952-parser-support</artifactId>
index e9e0d025c51085a1b80f66bb07750c817ffbc1b8..beac57fa3f931cae1f9cac54d383ab01afb0b652 100644 (file)
         <module>odlext-model-api</module>
         <module>odlext-parser-support</module>
 
+        <!-- NACM metamodel support -->
+        <module>rfc6536-model-api</module>
+        <module>rfc6536-parser-support</module>
+
         <!-- Metadata (annotation) metamodel support -->
         <module>rfc7952-model-api</module>
         <module>rfc7952-parser-support</module>
diff --git a/yang/rfc6536-model-api/pom.xml b/yang/rfc6536-model-api/pom.xml
new file mode 100644 (file)
index 0000000..89017ed
--- /dev/null
@@ -0,0 +1,81 @@
+<?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">
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>bundle-parent</artifactId>
+        <version>3.0.0-SNAPSHOT</version>
+        <relativePath/>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.opendaylight.yangtools</groupId>
+    <artifactId>rfc6536-model-api</artifactId>
+    <version>2.0.0-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+    <name>${project.artifactId}</name>
+    <description>RFC6536 metamodel</description>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>yangtools-artifacts</artifactId>
+                <version>2.0.0-SNAPSHOT</version>
+                <scope>import</scope>
+                <type>pom</type>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>concepts</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>yang-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>yang-model-api</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <!--
+        Maven Site Configuration
+
+        The following configuration is necessary for maven-site-plugin to
+        correctly identify the correct deployment path for OpenDaylight Maven
+        sites.
+    -->
+    <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+    <distributionManagement>
+        <site>
+            <id>opendaylight-site</id>
+            <url>${nexus.site.url}/${project.artifactId}/</url>
+        </site>
+    </distributionManagement>
+</project>
diff --git a/yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/DefaultDenyAllEffectiveStatement.java b/yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/DefaultDenyAllEffectiveStatement.java
new file mode 100644 (file)
index 0000000..6ec0f86
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies 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.yangtools.rfc6536.model.api;
+
+import com.google.common.annotations.Beta;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+
+/**
+ * Effective statement representation of 'default-deny-all' extension defined in
+ * <a href="https://tools.ietf.org/html/rfc6536">RFC6536</a>.
+ */
+@Beta
+public interface DefaultDenyAllEffectiveStatement extends EffectiveStatement<Void, DefaultDenyAllStatement>,
+        DefaultDenyAllSchemaNode {
+
+}
diff --git a/yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/DefaultDenyAllSchemaNode.java b/yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/DefaultDenyAllSchemaNode.java
new file mode 100644 (file)
index 0000000..7e79782
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies 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.yangtools.rfc6536.model.api;
+
+import com.google.common.annotations.Beta;
+import java.util.Optional;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+
+/**
+ * Represents the effect of 'default-deny-all' extension, as defined in
+ * <a href="https://tools.ietf.org/html/rfc6536">RFC6536</a>, being attached to a SchemaNode.
+ */
+@Beta
+public interface DefaultDenyAllSchemaNode extends UnknownSchemaNode {
+    /**
+     * Attempt to find a {@link DefaultDenyAllSchemaNode} in a parent {@link DataSchemaNode}.
+     *
+     * @param parent Parent to search
+     * @return {@link DefaultDenyAllSchemaNode} child, if present.
+     */
+    static Optional<DefaultDenyAllSchemaNode> findIn(final DataSchemaNode parent) {
+        return parent.getUnknownSchemaNodes().stream().filter(DefaultDenyAllSchemaNode.class::isInstance).findAny()
+                .map(DefaultDenyAllSchemaNode.class::cast);
+    }
+}
diff --git a/yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/DefaultDenyAllStatement.java b/yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/DefaultDenyAllStatement.java
new file mode 100644 (file)
index 0000000..33e82e4
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies 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.yangtools.rfc6536.model.api;
+
+import com.google.common.annotations.Beta;
+import org.opendaylight.yangtools.yang.model.api.stmt.UnknownStatement;
+
+/**
+ * Declared statement representation of 'default-deny-all' extension defined in
+ * <a href="https://tools.ietf.org/html/rfc6536">RFC6536</a>.
+ */
+@Beta
+public interface DefaultDenyAllStatement extends UnknownStatement<Void> {
+
+}
diff --git a/yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/DefaultDenyWriteEffectiveStatement.java b/yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/DefaultDenyWriteEffectiveStatement.java
new file mode 100644 (file)
index 0000000..24f3e0a
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies 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.yangtools.rfc6536.model.api;
+
+import com.google.common.annotations.Beta;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+
+/**
+ * Effective statement representation of 'default-deny-write' extension defined in
+ * <a href="https://tools.ietf.org/html/rfc6536">RFC6536</a>.
+ */
+@Beta
+public interface DefaultDenyWriteEffectiveStatement extends EffectiveStatement<Void, DefaultDenyWriteStatement>,
+        DefaultDenyWriteSchemaNode {
+
+}
diff --git a/yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/DefaultDenyWriteSchemaNode.java b/yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/DefaultDenyWriteSchemaNode.java
new file mode 100644 (file)
index 0000000..fc0f492
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies 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.yangtools.rfc6536.model.api;
+
+import com.google.common.annotations.Beta;
+import java.util.Optional;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+
+/**
+ * Represents the effect of 'default-deny-write' extension, as defined in
+ * <a href="https://tools.ietf.org/html/rfc6536">RFC6536</a>, being attached to a SchemaNode.
+ */
+@Beta
+public interface DefaultDenyWriteSchemaNode extends UnknownSchemaNode {
+    /**
+     * Attempt to find a {@link DefaultDenyWriteSchemaNode} in a parent {@link DataSchemaNode}.
+     *
+     * @param parent Parent to search
+     * @return {@link DefaultDenyWriteSchemaNode} child, if present.
+     */
+    static Optional<DefaultDenyWriteSchemaNode> findIn(final DataSchemaNode parent) {
+        return parent.getUnknownSchemaNodes().stream().filter(DefaultDenyWriteSchemaNode.class::isInstance).findAny()
+                .map(DefaultDenyWriteSchemaNode.class::cast);
+    }
+}
diff --git a/yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/DefaultDenyWriteStatement.java b/yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/DefaultDenyWriteStatement.java
new file mode 100644 (file)
index 0000000..9f004c7
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies 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.yangtools.rfc6536.model.api;
+
+import com.google.common.annotations.Beta;
+import org.opendaylight.yangtools.yang.model.api.stmt.UnknownStatement;
+
+/**
+ * Declared statement representation of 'default-deny-write' extension defined in
+ * <a href="https://tools.ietf.org/html/rfc6536">RFC6536</a>.
+ */
+@Beta
+public interface DefaultDenyWriteStatement extends UnknownStatement<Void> {
+
+}
diff --git a/yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/NACMConstants.java b/yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/NACMConstants.java
new file mode 100644 (file)
index 0000000..a7205f6
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies, 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.yangtools.rfc6536.model.api;
+
+import com.google.common.collect.ImmutableList;
+import java.net.URI;
+import java.util.Collection;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.Revision;
+import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+
+/**
+ * Constants associated with RFC6536.
+ *
+ * @author Robert Varga
+ */
+public final class NACMConstants {
+    private static final String MODULE_NAME = "ietf-netconf-acm";
+    private static final URI MODULE_NAMESPACE = URI.create("urn:ietf:params:xml:ns:yang:ietf-netconf-acm");
+    private static final Revision RFC6536_REVISION = Revision.of("2012-02-22");
+
+    /**
+     * Runtime RFC6536 identity.
+     */
+    public static final QNameModule RFC6536_MODULE = QNameModule.create(MODULE_NAMESPACE, RFC6536_REVISION).intern();
+
+    /**
+     * RFC6536 model source name.
+     */
+    public static final SourceIdentifier RFC6536_SOURCE = RevisionSourceIdentifier.create(MODULE_NAME,
+        RFC6536_REVISION);
+
+    /**
+     * Normative prefix to use when importing {@link #RFC6536_SOURCE}.
+     */
+    public static final String MODULE_PREFIX = "nacm";
+
+    private NACMConstants() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Return identifiers of all sources known to define NACM extension.
+     *
+     * @return Collection of identifiers.
+     */
+    public static Collection<SourceIdentifier> knownModelSources() {
+        return ImmutableList.of(RFC6536_SOURCE);
+    }
+}
diff --git a/yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/NACMStatements.java b/yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/NACMStatements.java
new file mode 100644 (file)
index 0000000..361c06f
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies, 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.yangtools.rfc6536.model.api;
+
+import static java.util.Objects.requireNonNull;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+
+/**
+ * {@link StatementDefinition}s for statements defined by RFC6536.
+ *
+ * @author Robert Varga
+ */
+public enum NACMStatements implements StatementDefinition {
+    DEFAULT_DENY_ALL(QName.create(NACMConstants.RFC6536_MODULE, "default-deny-all"), DefaultDenyAllStatement.class,
+        DefaultDenyAllEffectiveStatement.class),
+    DEFAULT_DENY_WRITE(QName.create(NACMConstants.RFC6536_MODULE, "default-deny-write"),
+        DefaultDenyWriteStatement.class, DefaultDenyWriteEffectiveStatement.class);
+
+    private final Class<? extends EffectiveStatement<?, ?>> effectiveRepresentation;
+    private final Class<? extends DeclaredStatement<?>> declaredRepresentation;
+    private final QName statementName;
+
+    NACMStatements(final QName statementName, final Class<? extends DeclaredStatement<?>> declaredRepresentation,
+            final Class<? extends EffectiveStatement<?, ?>> effectiveRepresentation) {
+        this.statementName = statementName.intern();
+        this.declaredRepresentation = requireNonNull(declaredRepresentation);
+        this.effectiveRepresentation = requireNonNull(effectiveRepresentation);
+    }
+
+    @Override
+    public QName getArgumentName() {
+        return null;
+    }
+
+    @Override
+    public boolean isArgumentYinElement() {
+        return false;
+    }
+
+    @Override
+    public QName getStatementName() {
+        return statementName;
+    }
+
+    @Override
+    public Class<? extends EffectiveStatement<?, ?>> getEffectiveRepresentationClass() {
+        return effectiveRepresentation;
+    }
+
+    @Override
+    public Class<? extends DeclaredStatement<?>> getDeclaredRepresentationClass() {
+        return declaredRepresentation;
+    }
+}
diff --git a/yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/package-info.java b/yang/rfc6536-model-api/src/main/java/org/opendaylight/yangtools/rfc6536/model/api/package-info.java
new file mode 100644 (file)
index 0000000..859918a
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies 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
+ */
+/**
+ * YANG metamodel extensions to support NACM, as defined in <a href="https://tools.ietf.org/html/rfc6536">RFC6536</a>.
+ *
+ * @author Robert Varga
+ */
+package org.opendaylight.yangtools.rfc6536.model.api;
diff --git a/yang/rfc6536-parser-support/pom.xml b/yang/rfc6536-parser-support/pom.xml
new file mode 100644 (file)
index 0000000..e192d13
--- /dev/null
@@ -0,0 +1,87 @@
+<?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">
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>bundle-parent</artifactId>
+        <version>3.0.0-SNAPSHOT</version>
+        <relativePath/>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.opendaylight.yangtools</groupId>
+    <artifactId>rfc6536-parser-support</artifactId>
+    <version>2.0.0-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+    <name>${project.artifactId}</name>
+    <description>RFC6536 parser support</description>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>yangtools-artifacts</artifactId>
+                <version>2.0.0-SNAPSHOT</version>
+                <scope>import</scope>
+                <type>pom</type>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>concepts</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>yang-common</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>rfc6536-model-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>yang-parser-rfc7950</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <!--
+        Maven Site Configuration
+
+        The following configuration is necessary for maven-site-plugin to
+        correctly identify the correct deployment path for OpenDaylight Maven
+        sites.
+    -->
+    <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+    <distributionManagement>
+        <site>
+            <id>opendaylight-site</id>
+            <url>${nexus.site.url}/${project.artifactId}/</url>
+        </site>
+    </distributionManagement>
+</project>
diff --git a/yang/rfc6536-parser-support/src/main/java/org/opendaylight/yangtools/rfc6536/parser/DefaultDenyAllStatementSupport.java b/yang/rfc6536-parser-support/src/main/java/org/opendaylight/yangtools/rfc6536/parser/DefaultDenyAllStatementSupport.java
new file mode 100644 (file)
index 0000000..c770f0c
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies, 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.yangtools.rfc6536.parser;
+
+import org.opendaylight.yangtools.rfc6536.model.api.DefaultDenyAllEffectiveStatement;
+import org.opendaylight.yangtools.rfc6536.model.api.DefaultDenyAllStatement;
+import org.opendaylight.yangtools.rfc6536.model.api.NACMStatements;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.UnknownEffectiveStatementBase;
+import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement;
+import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator;
+
+public final class DefaultDenyAllStatementSupport
+        extends AbstractStatementSupport<Void, DefaultDenyAllStatement, DefaultDenyAllEffectiveStatement> {
+
+    private static final class Declared extends AbstractDeclaredStatement<Void> implements DefaultDenyAllStatement {
+        Declared(final StmtContext<Void, ?, ?> context) {
+            super(context);
+        }
+
+        @Override
+        public Void getArgument() {
+            return null;
+        }
+    }
+
+    private static final class Effective extends UnknownEffectiveStatementBase<Void, DefaultDenyAllStatement>
+            implements DefaultDenyAllEffectiveStatement {
+
+        private final SchemaPath path;
+
+        Effective(final StmtContext<Void, DefaultDenyAllStatement, ?> ctx) {
+            super(ctx);
+            path = ctx.getParentContext().getSchemaPath().get().createChild(
+                ctx.getPublicDefinition().getStatementName());
+        }
+
+        @Override
+        public QName getQName() {
+            return path.getLastComponent();
+        }
+
+        @Override
+        public SchemaPath getPath() {
+            return path;
+        }
+    }
+
+    private static final DefaultDenyAllStatementSupport INSTANCE =
+            new DefaultDenyAllStatementSupport(NACMStatements.DEFAULT_DENY_ALL);
+
+    private final SubstatementValidator validator;
+
+    private DefaultDenyAllStatementSupport(final StatementDefinition definition) {
+        super(definition);
+        this.validator = SubstatementValidator.builder(definition).build();
+    }
+
+    public static DefaultDenyAllStatementSupport getInstance() {
+        return INSTANCE;
+    }
+
+    @Override
+    public DefaultDenyAllStatement createDeclared(final StmtContext<Void, DefaultDenyAllStatement, ?> ctx) {
+        return new Declared(ctx);
+    }
+
+    @Override
+    public DefaultDenyAllEffectiveStatement createEffective(
+            final StmtContext<Void, DefaultDenyAllStatement, DefaultDenyAllEffectiveStatement> ctx) {
+        return new Effective(ctx);
+    }
+
+    @Override
+    public Void parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
+        return null;
+    }
+
+    @Override
+    protected SubstatementValidator getSubstatementValidator() {
+        return validator;
+    }
+}
diff --git a/yang/rfc6536-parser-support/src/main/java/org/opendaylight/yangtools/rfc6536/parser/DefaultDenyWriteStatementSupport.java b/yang/rfc6536-parser-support/src/main/java/org/opendaylight/yangtools/rfc6536/parser/DefaultDenyWriteStatementSupport.java
new file mode 100644 (file)
index 0000000..002bcc5
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies, 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.yangtools.rfc6536.parser;
+
+import org.opendaylight.yangtools.rfc6536.model.api.DefaultDenyWriteEffectiveStatement;
+import org.opendaylight.yangtools.rfc6536.model.api.DefaultDenyWriteStatement;
+import org.opendaylight.yangtools.rfc6536.model.api.NACMStatements;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.UnknownEffectiveStatementBase;
+import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement;
+import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator;
+
+public final class DefaultDenyWriteStatementSupport
+    extends AbstractStatementSupport<Void, DefaultDenyWriteStatement, DefaultDenyWriteEffectiveStatement> {
+
+    private static final class Declared extends AbstractDeclaredStatement<Void> implements DefaultDenyWriteStatement {
+        Declared(final StmtContext<Void, ?, ?> context) {
+            super(context);
+        }
+
+        @Override
+        public Void getArgument() {
+            return null;
+        }
+    }
+
+    private static final class Effective extends UnknownEffectiveStatementBase<Void, DefaultDenyWriteStatement>
+            implements DefaultDenyWriteEffectiveStatement {
+
+        private final SchemaPath path;
+
+        Effective(final StmtContext<Void, DefaultDenyWriteStatement, ?> ctx) {
+            super(ctx);
+            path = ctx.getParentContext().getSchemaPath().get().createChild(
+                ctx.getPublicDefinition().getStatementName());
+        }
+
+        @Override
+        public QName getQName() {
+            return path.getLastComponent();
+        }
+
+        @Override
+        public SchemaPath getPath() {
+            return path;
+        }
+    }
+
+    private static final DefaultDenyWriteStatementSupport INSTANCE =
+            new DefaultDenyWriteStatementSupport(NACMStatements.DEFAULT_DENY_WRITE);
+
+    private final SubstatementValidator validator;
+
+    DefaultDenyWriteStatementSupport(final StatementDefinition definition) {
+        super(definition);
+        this.validator = SubstatementValidator.builder(definition).build();
+    }
+
+    public static DefaultDenyWriteStatementSupport getInstance() {
+        return INSTANCE;
+    }
+
+    @Override
+    public DefaultDenyWriteStatement createDeclared(final StmtContext<Void, DefaultDenyWriteStatement, ?> ctx) {
+        return new Declared(ctx);
+    }
+
+    @Override
+    public DefaultDenyWriteEffectiveStatement createEffective(
+            final StmtContext<Void, DefaultDenyWriteStatement, DefaultDenyWriteEffectiveStatement> ctx) {
+        return new Effective(ctx);
+    }
+
+    @Override
+    public Void parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
+        return null;
+    }
+
+    @Override
+    protected SubstatementValidator getSubstatementValidator() {
+        return validator;
+    }
+}
diff --git a/yang/rfc6536-parser-support/src/main/java/org/opendaylight/yangtools/rfc6536/parser/package-info.java b/yang/rfc6536-parser-support/src/main/java/org/opendaylight/yangtools/rfc6536/parser/package-info.java
new file mode 100644 (file)
index 0000000..eddffc7
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies 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
+ */
+/**
+ * YANG parser support for metamodel extensions defined in <a href="https://tools.ietf.org/html/rfc6536">RFC6536</a>.
+ * Add {@link org.opendaylight.yangtools.rfc6536.parser.DefaultDenyAllStatementSupport} and
+ * {@link org.opendaylight.yangtools.rfc6536.parser.DefaultDenyWriteStatementSupport} to your reactor to add support
+ * for this extension.
+ *
+ * @author Robert Varga
+ */
+package org.opendaylight.yangtools.rfc6536.parser;
diff --git a/yang/rfc6536-parser-support/src/test/java/org/opendaylight/yangtools/rfc6536/parser/NACMTest.java b/yang/rfc6536-parser-support/src/test/java/org/opendaylight/yangtools/rfc6536/parser/NACMTest.java
new file mode 100644 (file)
index 0000000..cab1230
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies, 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.yangtools.rfc6536.parser;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.yangtools.rfc6536.model.api.DefaultDenyAllSchemaNode;
+import org.opendaylight.yangtools.rfc6536.model.api.DefaultDenyWriteSchemaNode;
+import org.opendaylight.yangtools.rfc6536.model.api.NACMConstants;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+import org.opendaylight.yangtools.yang.parser.rfc7950.reactor.RFC7950Reactors;
+import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangStatementStreamSource;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
+import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor.BuildAction;
+
+public class NACMTest {
+    private static CrossSourceStatementReactor reactor;
+
+    @BeforeClass
+    public static void createReactor() {
+        reactor = RFC7950Reactors.defaultReactorBuilder()
+                .addStatementSupport(ModelProcessingPhase.FULL_DECLARATION,
+                    DefaultDenyAllStatementSupport.getInstance())
+                .addStatementSupport(ModelProcessingPhase.FULL_DECLARATION,
+                    DefaultDenyWriteStatementSupport.getInstance())
+                .build();
+    }
+
+    @Test
+    public void testResolution() throws ReactorException, IOException, YangSyntaxErrorException {
+        final BuildAction build = reactor.newBuild();
+        build.addSource(YangStatementStreamSource.create(
+            YangTextSchemaSource.forResource("/ietf-netconf-acm@2012-02-22.yang")));
+        build.addSource(YangStatementStreamSource.create(
+            YangTextSchemaSource.forResource("/ietf-yang-types@2013-07-15.yang")));
+        final SchemaContext context = build.buildEffective();
+
+        final Module module = context.findModule(NACMConstants.RFC6536_MODULE).get();
+        final DataSchemaNode nacm = module.findDataChildByName(QName.create(NACMConstants.RFC6536_MODULE, "nacm"))
+                .get();
+        assertTrue(DefaultDenyAllSchemaNode.findIn(nacm).isPresent());
+        assertFalse(DefaultDenyWriteSchemaNode.findIn(nacm).isPresent());
+    }
+}
diff --git a/yang/rfc6536-parser-support/src/test/resources/ietf-netconf-acm@2012-02-22.yang b/yang/rfc6536-parser-support/src/test/resources/ietf-netconf-acm@2012-02-22.yang
new file mode 100644 (file)
index 0000000..93ac229
--- /dev/null
@@ -0,0 +1,449 @@
+module ietf-netconf-acm {
+
+  namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-acm";
+
+  prefix "nacm";
+
+  import ietf-yang-types {
+    prefix yang;
+  }
+
+  organization
+    "IETF NETCONF (Network Configuration) Working Group";
+
+  contact
+    "WG Web:   <http://tools.ietf.org/wg/netconf/>
+     WG List:  <mailto:netconf@ietf.org>
+
+     WG Chair: Mehmet Ersue
+               <mailto:mehmet.ersue@nsn.com>
+
+     WG Chair: Bert Wijnen
+               <mailto:bertietf@bwijnen.net>
+
+     Editor:   Andy Bierman
+               <mailto:andy@yumaworks.com>
+
+     Editor:   Martin Bjorklund
+               <mailto:mbj@tail-f.com>";
+
+  description
+    "NETCONF Access Control Model.
+
+     Copyright (c) 2012 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 6536; see
+     the RFC itself for full legal notices.";
+
+  revision "2012-02-22" {
+    description
+      "Initial version";
+    reference
+      "RFC 6536: Network Configuration Protocol (NETCONF)
+                 Access Control Model";
+  }
+
+  /*
+   * Extension statements
+   */
+
+  extension default-deny-write {
+    description
+      "Used to indicate that the data model node
+       represents a sensitive security system parameter.
+
+       If present, and the NACM module is enabled (i.e.,
+       /nacm/enable-nacm object equals 'true'), the NETCONF server
+       will only allow the designated 'recovery session' to have
+       write access to the node.  An explicit access control rule is
+       required for all other users.
+
+       The 'default-deny-write' extension MAY appear within a data
+       definition statement.  It is ignored otherwise.";
+  }
+
+  extension default-deny-all {
+    description
+      "Used to indicate that the data model node
+       controls a very sensitive security system parameter.
+
+       If present, and the NACM module is enabled (i.e.,
+       /nacm/enable-nacm object equals 'true'), the NETCONF server
+       will only allow the designated 'recovery session' to have
+       read, write, or execute access to the node.  An explicit
+       access control rule is required for all other users.
+
+       The 'default-deny-all' extension MAY appear within a data
+       definition statement, 'rpc' statement, or 'notification'
+       statement.  It is ignored otherwise.";
+  }
+
+  /*
+   * Derived types
+   */
+
+  typedef user-name-type {
+    type string {
+      length "1..max";
+    }
+    description
+      "General Purpose Username string.";
+  }
+
+  typedef matchall-string-type {
+    type string {
+      pattern "\*";
+    }
+    description
+      "The string containing a single asterisk '*' is used
+       to conceptually represent all possible values
+       for the particular leaf using this data type.";
+  }
+
+  typedef access-operations-type {
+    type bits {
+      bit create {
+        description
+          "Any protocol operation that creates a
+           new data node.";
+      }
+      bit read {
+        description
+          "Any protocol operation or notification that
+           returns the value of a data node.";
+      }
+      bit update {
+        description
+          "Any protocol operation that alters an existing
+           data node.";
+      }
+      bit delete {
+        description
+          "Any protocol operation that removes a data node.";
+      }
+      bit exec {
+        description
+          "Execution access to the specified protocol operation.";
+      }
+    }
+    description
+      "NETCONF Access Operation.";
+  }
+
+  typedef group-name-type {
+    type string {
+      length "1..max";
+      pattern "[^\*].*";
+    }
+    description
+      "Name of administrative group to which
+       users can be assigned.";
+  }
+
+  typedef action-type {
+    type enumeration {
+      enum permit {
+        description
+          "Requested action is permitted.";
+      }
+      enum deny {
+        description
+          "Requested action is denied.";
+      }
+    }
+    description
+      "Action taken by the server when a particular
+       rule matches.";
+  }
+
+  typedef node-instance-identifier {
+    type yang:xpath1.0;
+    description
+      "Path expression used to represent a special
+       data node instance identifier string.
+
+       A node-instance-identifier value is an
+       unrestricted YANG instance-identifier expression.
+       All the same rules as an instance-identifier apply
+       except predicates for keys are optional.  If a key
+       predicate is missing, then the node-instance-identifier
+       represents all possible server instances for that key.
+
+       This XPath expression is evaluated in the following context:
+
+        o  The set of namespace declarations are those in scope on
+           the leaf element where this type is used.
+
+        o  The set of variable bindings contains one variable,
+           'USER', which contains the name of the user of the current
+            session.
+
+        o  The function library is the core function library, but
+           note that due to the syntax restrictions of an
+           instance-identifier, no functions are allowed.
+
+        o  The context node is the root node in the data tree.";
+  }
+
+  /*
+   * Data definition statements
+   */
+
+  container nacm {
+    nacm:default-deny-all;
+
+    description
+      "Parameters for NETCONF Access Control Model.";
+
+    leaf enable-nacm {
+      type boolean;
+      default true;
+      description
+        "Enables or disables all NETCONF access control
+         enforcement.  If 'true', then enforcement
+         is enabled.  If 'false', then enforcement
+         is disabled.";
+    }
+
+    leaf read-default {
+      type action-type;
+      default "permit";
+      description
+        "Controls whether read access is granted if
+         no appropriate rule is found for a
+         particular read request.";
+    }
+
+    leaf write-default {
+      type action-type;
+      default "deny";
+      description
+        "Controls whether create, update, or delete access
+         is granted if no appropriate rule is found for a
+         particular write request.";
+    }
+
+    leaf exec-default {
+      type action-type;
+      default "permit";
+      description
+        "Controls whether exec access is granted if no appropriate
+         rule is found for a particular protocol operation request.";
+    }
+
+    leaf enable-external-groups {
+      type boolean;
+      default true;
+      description
+        "Controls whether the server uses the groups reported by the
+         NETCONF transport layer when it assigns the user to a set of
+         NACM groups.  If this leaf has the value 'false', any group
+         names reported by the transport layer are ignored by the
+         server.";
+    }
+
+    leaf denied-operations {
+      type yang:zero-based-counter32;
+      config false;
+      mandatory true;
+      description
+        "Number of times since the server last restarted that a
+         protocol operation request was denied.";
+    }
+
+    leaf denied-data-writes {
+      type yang:zero-based-counter32;
+      config false;
+      mandatory true;
+      description
+        "Number of times since the server last restarted that a
+         protocol operation request to alter
+         a configuration datastore was denied.";
+    }
+
+    leaf denied-notifications {
+      type yang:zero-based-counter32;
+      config false;
+      mandatory true;
+      description
+        "Number of times since the server last restarted that
+         a notification was dropped for a subscription because
+         access to the event type was denied.";
+    }
+
+    container groups {
+      description
+        "NETCONF Access Control Groups.";
+
+      list group {
+        key name;
+
+        description
+          "One NACM Group Entry.  This list will only contain
+           configured entries, not any entries learned from
+           any transport protocols.";
+
+        leaf name {
+          type group-name-type;
+          description
+            "Group name associated with this entry.";
+        }
+
+        leaf-list user-name {
+          type user-name-type;
+          description
+            "Each entry identifies the username of
+             a member of the group associated with
+             this entry.";
+        }
+      }
+    }
+
+    list rule-list {
+      key "name";
+      ordered-by user;
+      description
+        "An ordered collection of access control rules.";
+
+      leaf name {
+        type string {
+          length "1..max";
+        }
+        description
+          "Arbitrary name assigned to the rule-list.";
+      }
+      leaf-list group {
+        type union {
+          type matchall-string-type;
+          type group-name-type;
+        }
+        description
+          "List of administrative groups that will be
+           assigned the associated access rights
+           defined by the 'rule' list.
+
+           The string '*' indicates that all groups apply to the
+           entry.";
+      }
+
+      list rule {
+        key "name";
+        ordered-by user;
+        description
+          "One access control rule.
+
+           Rules are processed in user-defined order until a match is
+           found.  A rule matches if 'module-name', 'rule-type', and
+           'access-operations' match the request.  If a rule
+           matches, the 'action' leaf determines if access is granted
+           or not.";
+
+        leaf name {
+          type string {
+            length "1..max";
+          }
+          description
+            "Arbitrary name assigned to the rule.";
+        }
+
+        leaf module-name {
+          type union {
+            type matchall-string-type;
+            type string;
+          }
+          default "*";
+          description
+            "Name of the module associated with this rule.
+
+             This leaf matches if it has the value '*' or if the
+             object being accessed is defined in the module with the
+             specified module name.";
+        }
+        choice rule-type {
+          description
+            "This choice matches if all leafs present in the rule
+             match the request.  If no leafs are present, the
+             choice matches all requests.";
+          case protocol-operation {
+            leaf rpc-name {
+              type union {
+                type matchall-string-type;
+                type string;
+              }
+              description
+                "This leaf matches if it has the value '*' or if
+                 its value equals the requested protocol operation
+                 name.";
+            }
+          }
+          case notification {
+            leaf notification-name {
+              type union {
+                type matchall-string-type;
+                type string;
+              }
+              description
+                "This leaf matches if it has the value '*' or if its
+                 value equals the requested notification name.";
+            }
+          }
+          case data-node {
+            leaf path {
+              type node-instance-identifier;
+              mandatory true;
+              description
+                "Data Node Instance Identifier associated with the
+                 data node controlled by this rule.
+
+                 Configuration data or state data instance
+                 identifiers start with a top-level data node.  A
+                 complete instance identifier is required for this
+                 type of path value.
+
+                 The special value '/' refers to all possible
+                 datastore contents.";
+            }
+          }
+        }
+
+        leaf access-operations {
+          type union {
+            type matchall-string-type;
+            type access-operations-type;
+          }
+          default "*";
+          description
+            "Access operations associated with this rule.
+
+             This leaf matches if it has the value '*' or if the
+             bit corresponding to the requested operation is set.";
+        }
+
+        leaf action {
+          type action-type;
+          mandatory true;
+          description
+            "The access control action associated with the
+             rule.  If a rule is determined to match a
+             particular request, then this object is used
+             to determine whether to permit or deny the
+             request.";
+        }
+
+        leaf comment {
+          type string;
+          description
+            "A textual description of the access rule.";
+        }
+      }
+    }
+  }
+}
diff --git a/yang/rfc6536-parser-support/src/test/resources/ietf-yang-types@2013-07-15.yang b/yang/rfc6536-parser-support/src/test/resources/ietf-yang-types@2013-07-15.yang
new file mode 100644 (file)
index 0000000..bdff18c
--- /dev/null
@@ -0,0 +1,467 @@
+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 Kessens
+                 <mailto:david.kessens@nsn.com>
+
+       WG Chair: Juergen Schoenwaelder
+                 <mailto:j.schoenwaelder@jacobs-university.de>
+
+       Editor:   Juergen Schoenwaelder
+                 <mailto:j.schoenwaelder@jacobs-university.de>";
+
+     description
+      "This module contains a collection of generally useful derived
+       YANG data types.
+
+       Copyright (c) 2013 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 6991; see
+       the RFC itself for full legal notices.";
+
+     revision 2013-07-15 {
+       description
+        "This revision adds the following new data types:
+         - yang-identifier
+         - hex-string
+         - uuid
+         - dotted-quad";
+       reference
+        "RFC 6991: Common YANG Data Types";
+     }
+
+     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-identifiers.  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)";
+     }
+
+     typedef yang-identifier {
+       type string {
+         length "1..max";
+         pattern '[a-zA-Z_][a-zA-Z0-9\-_.]*';
+         pattern '.|..|[^xX].*|.[^mM].*|..[^lL].*';
+       }
+       description
+         "A YANG identifier string as defined by the 'identifier'
+          rule in Section 12 of RFC 6020.  An identifier must
+          start with an alphabetic character or an underscore
+          followed by an arbitrary sequence of alphabetic or
+          numeric characters, underscores, hyphens, or dots.
+
+          A YANG identifier MUST NOT start with any possible
+          combination of the lowercase or uppercase character
+          sequence 'xml'.";
+       reference
+         "RFC 6020: YANG - A Data Modeling Language for the Network
+                    Configuration Protocol (NETCONF)";
+     }
+     /*** collection of types related to date and time***/
+
+     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";
+     }
+
+     /*** collection of string types ***/
+
+     typedef hex-string {
+       type string {
+         pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?';
+       }
+       description
+        "A hexadecimal string with octets represented as hex digits
+         separated by colons.  The canonical representation uses
+         lowercase characters.";
+     }
+
+     typedef uuid {
+       type string {
+         pattern '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-'
+               + '[0-9a-fA-F]{4}-[0-9a-fA-F]{12}';
+       }
+       description
+        "A Universally Unique IDentifier in the string representation
+         defined in RFC 4122.  The canonical representation uses
+         lowercase characters.
+
+         The following is an example of a UUID in string representation:
+         f81d4fae-7dec-11d0-a765-00a0c91e6bf6
+         ";
+       reference
+        "RFC 4122: A Universally Unique IDentifier (UUID) URN
+                   Namespace";
+     }
+
+     typedef dotted-quad {
+       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])';
+       }
+       description
+         "An unsigned 32-bit number expressed in the dotted-quad
+          notation, i.e., four octets written as decimal numbers
+          and separated with the '.' (full stop) character.";
+     }
+   }
\ No newline at end of file
index 6ce01b6741b63a09f3a3d6557241007c04c9075f..260ef3d901651fcc77a3a24fbf57cdff6a7c9a37 100644 (file)
             <groupId>${project.groupId}</groupId>
             <artifactId>openconfig-parser-support</artifactId>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>rfc6536-model-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>rfc6536-parser-support</artifactId>
+        </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>rfc7952-model-api</artifactId>
index 81f2c7ccd59ac080337cd992a4606b170806bdeb..b05d42da60b1d7b37db8f4771cfb30736f5f4592 100644 (file)
@@ -13,6 +13,8 @@ import org.opendaylight.yangtools.odlext.parser.AnyxmlSchemaLocationStatementSup
 import org.opendaylight.yangtools.odlext.parser.AnyxmlStatementSupportOverride;
 import org.opendaylight.yangtools.openconfig.parser.EncryptedValueStatementSupport;
 import org.opendaylight.yangtools.openconfig.parser.HashedValueStatementSupport;
+import org.opendaylight.yangtools.rfc6536.parser.DefaultDenyAllStatementSupport;
+import org.opendaylight.yangtools.rfc6536.parser.DefaultDenyWriteStatementSupport;
 import org.opendaylight.yangtools.rfc7952.parser.AnnotationStatementSupport;
 import org.opendaylight.yangtools.rfc8040.parser.YangDataStatementSupport;
 import org.opendaylight.yangtools.yang.parser.rfc7950.reactor.CustomCrossSourceStatementReactorBuilder;
@@ -59,6 +61,12 @@ public final class DefaultReactors {
                 .overrideStatementSupport(ModelProcessingPhase.FULL_DECLARATION,
                     AnyxmlStatementSupportOverride.getInstance())
 
+                // RFC6536 default-deny-{all,write} support
+                .addStatementSupport(ModelProcessingPhase.FULL_DECLARATION,
+                    DefaultDenyAllStatementSupport.getInstance())
+                .addStatementSupport(ModelProcessingPhase.FULL_DECLARATION,
+                    DefaultDenyWriteStatementSupport.getInstance())
+
                 // RFC7952 annotation support
                 .addStatementSupport(ModelProcessingPhase.FULL_DECLARATION, AnnotationStatementSupport.getInstance())