<artifactId>restconf-common</artifactId>
<version>${project.version}</version>
</dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>restconf-nb-bierman02</artifactId>
- <version>${project.version}</version>
- </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>restconf-nb-rfc8040</artifactId>
<type>xml</type>
<classifier>features</classifier>
</dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>odl-restconf-nb-bierman02</artifactId>
- <version>${project.version}</version>
- <type>xml</type>
- <classifier>features</classifier>
- </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>odl-restconf-nb-rfc8040</artifactId>
<type>xml</type>
<classifier>features</classifier>
</dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>odl-restconf-nb-bierman02</artifactId>
- <type>xml</type>
- <classifier>features</classifier>
- </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>odl-restconf-nb-rfc8040</artifactId>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright © 2019 Pantheon Technologies, s.r.o. and others.
-
- 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>feature-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../../parent</relativePath>
- </parent>
-
- <artifactId>odl-restconf-nb-bierman02</artifactId>
- <packaging>feature</packaging>
- <name>OpenDaylight :: Restconf :: NB :: bierman02</name>
-
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.netconf</groupId>
- <artifactId>odl-netconf-mapping-api</artifactId>
- <type>xml</type>
- <classifier>features</classifier>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.netconf</groupId>
- <artifactId>odl-restconf-common</artifactId>
- <type>xml</type>
- <classifier>features</classifier>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.netconf</groupId>
- <artifactId>restconf-nb-bierman02</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.netconf</groupId>
- <artifactId>sal-rest-connector-config</artifactId>
- <type>cfg</type>
- <classifier>restconf</classifier>
- </dependency>
-
- <!-- TODO: Remove this when RESTCONF is converted to GSON -->
- <dependency>
- <groupId>org.json</groupId>
- <artifactId>json</artifactId>
- <version>20131018</version>
- </dependency>
- </dependencies>
-</project>
<module>odl-mdsal-apidocs</module>
<module>odl-restconf</module>
<module>odl-restconf-common</module>
- <module>odl-restconf-nb-bierman02</module>
<module>odl-restconf-nb-rfc8040</module>
</modules>
<module>restconf-models</module>
<module>restconf-common-models</module>
<module>restconf-common</module>
- <module>restconf-nb-bierman02</module>
<module>restconf-nb-rfc8040</module>
<module>sal-rest-connector-config</module>
<module>sal-rest-docgen</module>
+++ /dev/null
-/*
- * 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.restconf.common.util;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-public final class IdentityValuesDTO {
-
- private final List<IdentityValue> elementData = new ArrayList<>();
- private final String originValue;
-
- public IdentityValuesDTO(
- final String namespace, final String value, final String prefix, final String originValue) {
- elementData.add(new IdentityValue(namespace, value));
- this.originValue = originValue;
- }
-
- public IdentityValuesDTO(final String originValue) {
- this.originValue = originValue;
- }
-
- public IdentityValuesDTO() {
- originValue = null;
- }
-
- public void add(final String namespace, final String value, final String prefix) {
- elementData.add(new IdentityValue(namespace, value));
- }
-
- public void add(final IdentityValue identityValue) {
- elementData.add(identityValue);
- }
-
- public List<IdentityValue> getValuesWithNamespaces() {
- return Collections.unmodifiableList(elementData);
- }
-
- @Override
- public String toString() {
- return elementData.toString();
- }
-
- public String getOriginValue() {
- return originValue;
- }
-
- public static final class IdentityValue {
-
- private final String namespace;
- private final String value;
- private List<Predicate> predicates;
-
- public IdentityValue(final String namespace, final String value) {
- this.namespace = namespace;
- this.value = value;
- }
-
- public String getNamespace() {
- return namespace;
- }
-
- public String getValue() {
- return value;
- }
-
-
- public List<Predicate> getPredicates() {
- if (predicates == null) {
- return Collections.emptyList();
- }
- return Collections.unmodifiableList(predicates);
- }
-
- public void setPredicates(final List<Predicate> predicates) {
- this.predicates = predicates;
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- if (namespace != null) {
- sb.append(namespace);
- }
- if (value != null) {
- sb.append(" - ").append(value);
- }
- if (predicates != null && !predicates.isEmpty()) {
- for (final Predicate predicate : predicates) {
- sb.append("[").append(predicate.toString()).append("]");
- }
- }
- return sb.toString();
- }
-
- }
-
- public static final class Predicate {
-
- private final IdentityValue name;
- private final String value;
-
- public Predicate(final IdentityValue name, final String value) {
- this.name = name;
- this.value = value;
- }
-
- public IdentityValue getName() {
- return name;
- }
-
- public String getValue() {
- return value;
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- if (name != null) {
- sb.append(name.toString());
- }
- if (value != null) {
- sb.append("=").append(value);
- }
- return sb.toString();
- }
-
- public boolean isLeafList() {
- return name == null;
- }
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 Inocybe Technologies 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.restconf.common.util;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import javax.ws.rs.core.MultivaluedMap;
-
-/**
- * A hash table based implementation of {@link MultivaluedMap} interface.
- *
- * @deprecated Use {@link javax.ws.rs.core.MultivaluedHashMap} instead.
- * @author Thomas Pantelis
- */
-@Deprecated(since = "2.0.1", forRemoval = true)
-// FIXME: 3.0.0: remove this class
-public class MultivaluedHashMap<K, V> implements MultivaluedMap<K, V> {
- private final Map<K, List<V>> store = new HashMap<>();
-
- @Override
- public final void putSingle(K key, V value) {
- List<V> values = getValues(key);
-
- values.clear();
- if (value != null) {
- values.add(value);
- }
- }
-
- @Override
- public void add(K key, V value) {
- List<V> values = getValues(key);
-
- if (value != null) {
- values.add(value);
- }
- }
-
- @Override
- @SafeVarargs
- public final void addAll(K key, V... newValues) {
- addAll(key, Arrays.asList(newValues));
- }
-
- @Override
- public void addAll(K key, List<V> valueList) {
- Objects.requireNonNull(valueList, "Supplied list of values must not be null.");
-
- if (valueList.isEmpty()) {
- return;
- }
-
- List<V> values = getValues(key);
- for (V value : valueList) {
- if (value != null) {
- values.add(value);
- }
- }
- }
-
- @Override
- public void addFirst(K key, V value) {
- List<V> values = getValues(key);
-
- if (value != null) {
- values.add(0, value);
- }
- }
-
- @Override
- public V getFirst(K key) {
- List<V> values = store.get(key);
- return values == null || values.isEmpty() ? null : values.get(0);
- }
-
- @Override
- public boolean equalsIgnoreValueOrder(MultivaluedMap<K, V> omap) {
- if (this == omap) {
- return true;
- }
- if (!keySet().equals(omap.keySet())) {
- return false;
- }
- for (Entry<K, List<V>> e : entrySet()) {
- List<V> olist = omap.get(e.getKey());
- if (e.getValue().size() != olist.size()) {
- return false;
- }
- for (V v : e.getValue()) {
- if (!olist.contains(v)) {
- return false;
- }
- }
- }
- return true;
- }
-
- @Override
- public Collection<List<V>> values() {
- return store.values();
- }
-
- @Override
- public int size() {
- return store.size();
- }
-
- @Override
- public List<V> remove(Object key) {
- return store.remove(key);
- }
-
- @Override
- public void putAll(Map<? extends K, ? extends List<V>> map) {
- store.putAll(map);
- }
-
- @Override
- public List<V> put(K key, List<V> value) {
- return store.put(key, value);
- }
-
- @Override
- public Set<K> keySet() {
- return store.keySet();
- }
-
- @Override
- public boolean isEmpty() {
- return store.isEmpty();
- }
-
- @Override
- public List<V> get(Object key) {
- return store.get(key);
- }
-
- @Override
- public Set<Entry<K, List<V>>> entrySet() {
- return store.entrySet();
- }
-
- @Override
- public boolean containsValue(Object value) {
- return store.containsValue(value);
- }
-
- @Override
- public boolean containsKey(Object key) {
- return store.containsKey(key);
- }
-
- @Override
- public void clear() {
- store.clear();
- }
-
- private List<V> getValues(K key) {
- return store.computeIfAbsent(key, k -> new LinkedList<>());
- }
-}
+++ /dev/null
-/*
- * 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.restconf.common.util;
-
-import static java.util.Objects.requireNonNull;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PushbackInputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.xml.stream.events.StartElement;
-import org.opendaylight.restconf.common.util.IdentityValuesDTO.IdentityValue;
-import org.opendaylight.restconf.common.util.IdentityValuesDTO.Predicate;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-
-public final class RestUtil {
-
- // FIXME: BUG-1275: this is code duplicates data.impl.codec
-
- public static final String SQUOTE = "'";
- public static final String DQUOTE = "\"";
- private static final Pattern PREDICATE_PATTERN = Pattern.compile("\\[(.*?)\\]");
-
- private RestUtil() {
- }
-
- public static TypeDefinition<?> resolveBaseTypeFrom(final TypeDefinition<?> type) {
- TypeDefinition<?> superType = type;
- while (superType.getBaseType() != null) {
- superType = superType.getBaseType();
- }
- return superType;
- }
-
- /**
- * Utility method to find out if is provided {@link InputStream} empty.
- *
- * @param entityStream {@link InputStream} to be checked if it is empty.
- * @return Empty Optional if provided input stream is empty or Optional
- * containing input stream otherwise.
- *
- * @throws IOException if an IO error arises during stream inspection.
- * @throws NullPointerException if provided stream is null.
- *
- */
- public static Optional<InputStream> isInputStreamEmpty(final InputStream entityStream) throws IOException {
- final PushbackInputStream pushbackInputStream = new PushbackInputStream(requireNonNull(entityStream));
-
- int firstByte = pushbackInputStream.read();
- if (firstByte == -1) {
- return Optional.empty();
- } else {
- pushbackInputStream.unread(firstByte);
- return Optional.of(pushbackInputStream);
- }
- }
-
- public static IdentityValuesDTO asInstanceIdentifier(final String value, final PrefixesMaping prefixMap) {
- final String valueTrimmed = value.trim();
- if (!valueTrimmed.startsWith("/")) {
- return null;
- }
- final String[] xPathParts = valueTrimmed.split("/");
- if (xPathParts.length < 2) { // must be at least "/pr:node"
- return null;
- }
- final IdentityValuesDTO identityValuesDTO = new IdentityValuesDTO(value);
- for (int i = 1; i < xPathParts.length; i++) {
- final String xPathPartTrimmed = xPathParts[i].trim();
-
- final String xPathPartStr = getIdAndPrefixAsStr(xPathPartTrimmed);
- final IdentityValue identityValue = toIdentity(xPathPartStr, prefixMap);
- if (identityValue == null) {
- return null;
- }
-
- final List<Predicate> predicates = toPredicates(xPathPartTrimmed, prefixMap);
- if (predicates == null) {
- return null;
- }
- identityValue.setPredicates(predicates);
-
- identityValuesDTO.add(identityValue);
- }
- return identityValuesDTO.getValuesWithNamespaces().isEmpty() ? null : identityValuesDTO;
- }
-
- private static String getIdAndPrefixAsStr(final String pathPart) {
- final int predicateStartIndex = pathPart.indexOf("[");
- return predicateStartIndex == -1 ? pathPart : pathPart.substring(0, predicateStartIndex);
- }
-
- private static IdentityValue toIdentity(final String xpathPart, final PrefixesMaping prefixMap) {
- final String xPathPartTrimmed = xpathPart.trim();
- if (xPathPartTrimmed.isEmpty()) {
- return null;
- }
- final String[] prefixAndIdentifier = xPathPartTrimmed.split(":");
- // it is not "prefix:value"
- if (prefixAndIdentifier.length != 2) {
- return null;
- }
- final String prefix = prefixAndIdentifier[0].trim();
- final String identifier = prefixAndIdentifier[1].trim();
- if (prefix.isEmpty() || identifier.isEmpty()) {
- return null;
- }
- final String namespace = prefixMap.getNamespace(prefix);
- return new IdentityValue(namespace, identifier);
- }
-
- private static List<Predicate> toPredicates(final String predicatesStr, final PrefixesMaping prefixMap) {
- final List<Predicate> result = new ArrayList<>();
- final List<String> predicates = new ArrayList<>();
- final Matcher matcher = PREDICATE_PATTERN.matcher(predicatesStr);
- while (matcher.find()) {
- predicates.add(matcher.group(1).trim());
- }
- for (final String predicate : predicates) {
- final int indexOfEqualityMark = predicate.indexOf("=");
- if (indexOfEqualityMark != -1) {
- final String predicateValue = toPredicateValue(predicate.substring(indexOfEqualityMark + 1));
- if (predicate.startsWith(".")) { // it is leaf-list
- if (predicateValue == null) {
- return null;
- }
- result.add(new Predicate(null, predicateValue));
- } else {
- final IdentityValue identityValue =
- toIdentity(predicate.substring(0, indexOfEqualityMark), prefixMap);
- if (identityValue == null || predicateValue == null) {
- return null;
- }
- result.add(new Predicate(identityValue, predicateValue));
- }
- }
- }
- return result;
- }
-
- private static String toPredicateValue(final String predicatedValue) {
- final String predicatedValueTrimmed = predicatedValue.trim();
- if ((predicatedValueTrimmed.startsWith(DQUOTE) || predicatedValueTrimmed.startsWith(SQUOTE))
- && (predicatedValueTrimmed.endsWith(DQUOTE) || predicatedValueTrimmed.endsWith(SQUOTE))) {
- return predicatedValueTrimmed.substring(1, predicatedValueTrimmed.length() - 1);
- }
- return null;
- }
-
- public interface PrefixesMaping {
- String getNamespace(String prefix);
- }
-
- public static class PrefixMapingFromXml implements PrefixesMaping {
- StartElement startElement = null;
-
- public PrefixMapingFromXml(final StartElement startElement) {
- this.startElement = startElement;
- }
-
- @Override
- public String getNamespace(final String prefix) {
- return startElement.getNamespaceContext().getNamespaceURI(prefix);
- }
- }
-
- public static class PrefixMapingFromJson implements PrefixesMaping {
-
- @Override
- public String getNamespace(final String prefix) {
- return prefix;
- }
- }
-
-}
+++ /dev/null
-/*
- * 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.restconf.common.util;
-
-import java.util.Collection;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.common.ErrorType;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-
-/**
- * Util class for finding {@link DataSchemaNode}.
- *
- */
-public final class RestconfSchemaUtil {
- private RestconfSchemaUtil() {
- // Hidden on purpose
- }
-
- /**
- * Find child of {@link SchemaNode} in {@link Collection} by {@link String}
- * schema node name.
- *
- * @param <T>
- * child of SchemaNode
- * @param collection
- * child of node
- * @param schemaNodeName
- * schema node name
- * @return {@link SchemaNode}
- */
- public static <T extends SchemaNode> T findSchemaNodeInCollection(final Collection<T> collection,
- final String schemaNodeName) {
- for (final T child : collection) {
- if (child.getQName().getLocalName().equals(schemaNodeName)) {
- return child;
- }
- }
- throw new RestconfDocumentedException("Schema node " + schemaNodeName + " does not exist in module.",
- ErrorType.PROTOCOL, ErrorTag.DATA_MISSING);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.restconf.common.validation;
-
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.common.ErrorType;
-
-/**
- * sal-rest-connector
- * org.opendaylight.controller.md.sal.rest.common
- *
- * <p>
- * Utility class is centralizing all needed validation functionality for a Restconf osgi module.
- * All methods have to throw {@link RestconfDocumentedException} only, which is a representation
- * for all error situation followed by restconf-netconf specification.
- * See also <a href="https://tools.ietf.org/html/draft-bierman-netconf-restconf-02">RESTCONF</a>.
- */
-public final class RestconfValidationUtils {
- private RestconfValidationUtils() {
- // Hidden on purpose
- }
-
- /**
- * Method returns {@link RestconfDocumentedException} if value is NULL or same input value.
- * {@link ErrorType} is relevant for server application layer
- * {@link ErrorTag} is 404 data-missing
- * See also <a href="https://tools.ietf.org/html/draft-bierman-netconf-restconf-02">RESTCONF</a>.
- *
- * @param value - some value from {@link org.opendaylight.yangtools.yang.model.api.Module}
- * @param moduleName - name of {@link org.opendaylight.yangtools.yang.model.api.Module}
- * @return - T value (same input value)
- */
- public static <T> T checkNotNullDocumented(final T value, final String moduleName) {
- if (value == null) {
- final String errMsg = "Module " + moduleName + " was not found.";
- throw new RestconfDocumentedException(errMsg, ErrorType.APPLICATION, ErrorTag.DATA_MISSING);
- }
- return value;
- }
-}
+++ /dev/null
-/*
- * 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.restconf.common.util;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.junit.Assert;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-
-/**
- * Unit tests for {@link RestconfSchemaUtil}.
- */
-public class RestconfSchemaUtilTest {
-
- @Test
- public void findInCollectionTest() {
- final SchemaNode origSchNode = mockSchemaNode("key");
- final SchemaNode actualSch = findSchemaNodeInCollection("key", origSchNode);
- Assert.assertEquals(origSchNode, actualSch);
- }
-
- @Test(expected = RuntimeException.class)
- public void findInCollectionFailedTest() {
- final SchemaNode origSchNode = mockSchemaNode("key");
- findSchemaNodeInCollection("bad_key", origSchNode);
- }
-
- private static SchemaNode findSchemaNodeInCollection(final String key, final SchemaNode... origSchNode) {
- final List<SchemaNode> collection = new ArrayList<>();
- for (final SchemaNode element : origSchNode) {
- collection.add(element);
- }
- return RestconfSchemaUtil.findSchemaNodeInCollection(collection, key);
- }
-
- private static SchemaNode mockSchemaNode(final String origKey) {
- final SchemaNode mockSchNode = Mockito.mock(SchemaNode.class);
- Mockito.when(mockSchNode.getQName())
- .thenReturn(QName.create("ns", "2016-10-10", origKey));
- return mockSchNode;
- }
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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
--->
-<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>4.0.0-SNAPSHOT</version>
- <relativePath>../../parent</relativePath>
- </parent>
-
- <artifactId>restconf-nb-bierman02</artifactId>
- <packaging>bundle</packaging>
-
- <dependencies>
- <dependency>
- <groupId>javax.annotation</groupId>
- <artifactId>javax.annotation-api</artifactId>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>com.guicedee.services</groupId>
- <artifactId>javax.inject</artifactId>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.netconf</groupId>
- <artifactId>restconf-common-models</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.netconf</groupId>
- <artifactId>restconf-common</artifactId>
- </dependency>
- <dependency>
- <groupId>org.glassfish.jersey.inject</groupId>
- <artifactId>jersey-hk2</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.mdsal</groupId>
- <artifactId>mdsal-dom-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.mdsal</groupId>
- <artifactId>mdsal-dom-spi</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.code.gson</groupId>
- <artifactId>gson</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-codec-http</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-model-util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-codec-gson</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-codec-xml</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-model-export</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.mdsal.binding.model.ietf</groupId>
- <artifactId>rfc6991-ietf-inet-types</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.mdsal.binding.model.ietf</groupId>
- <artifactId>rfc6991-ietf-yang-types</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.netconf</groupId>
- <artifactId>netconf-util</artifactId>
- </dependency>
- <dependency>
- <groupId>net.java.dev.stax-utils</groupId>
- <artifactId>stax-utils</artifactId>
- <exclusions>
- <exclusion>
- <!-- JSR173 ships with JRE by default -->
- <groupId>com.bea.xml</groupId>
- <artifactId>jsr173-ri</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.json</groupId>
- <artifactId>json</artifactId>
- <version>20131018</version>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.aaa.web</groupId>
- <artifactId>web-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.aaa.web</groupId>
- <artifactId>servlet-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.aaa</groupId>
- <artifactId>aaa-filterchain</artifactId>
- </dependency>
-
- <!-- Testing Dependencies -->
- <dependency>
- <groupId>org.glassfish.jersey.test-framework.providers</groupId>
- <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.aaa</groupId>
- <artifactId>aaa-shiro-api</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>testutils</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.mdsal</groupId>
- <artifactId>mdsal-binding-test-utils</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.mdsal</groupId>
- <artifactId>mdsal-binding-dom-adapter</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava-testlib</artifactId>
- </dependency>
- <dependency>
- <groupId>org.skyscreamer</groupId>
- <artifactId>jsonassert</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.aaa.web</groupId>
- <artifactId>testutils</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.infrautils</groupId>
- <artifactId>inject.guice.testutils</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-test-util</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Bundle-Name>MD SAL Restconf Connector</Bundle-Name>
- <Private-Package>org.opendaylight.netconf.sal.rest.*,
- org.opendaylight.netconf.sal.restconf.rpc.*,
- org.opendaylight.netconf.sal.restconf.impl.*,
- org.opendaylight.netconf.md.sal.rest.common.*,
- org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.rest.connector.rev140724.*,
- </Private-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <scm>
- <connection>scm:git:ssh://git.opendaylight.org:29418/netconf.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/netconf.git</developerConnection>
- <tag>HEAD</tag>
- <url>https://git.opendaylight.org/gerrit/gitweb?p=netconf.git;a=summary</url>
- </scm>
-</project>
+++ /dev/null
-/*
- * 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.md.sal.rest.schema;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import java.util.concurrent.ExecutionException;
-import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.ext.MessageBodyWriter;
-import javax.ws.rs.ext.Provider;
-import org.opendaylight.restconf.common.schema.SchemaExportContext;
-import org.opendaylight.yangtools.yang.common.YangConstants;
-import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
-import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
-
-@Provider
-@Produces({ YangConstants.RFC6020_YANG_MEDIA_TYPE })
-public class SchemaExportContentYangBodyWriter implements MessageBodyWriter<SchemaExportContext> {
-
- @Override
- public boolean isWriteable(final Class<?> type, final Type genericType, final Annotation[] annotations,
- final MediaType mediaType) {
- return type.equals(SchemaExportContext.class);
- }
-
- @Override
- public long getSize(final SchemaExportContext context, final Class<?> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType) {
- return -1;
- }
-
- @Override
- public void writeTo(final SchemaExportContext context, final Class<?> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType,
- final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream) throws IOException,
- WebApplicationException {
- final RevisionSourceIdentifier sourceId = RevisionSourceIdentifier.create(context.getModule().getName(),
- context.getModule().getQNameModule().getRevision());
- final YangTextSchemaSource yangTextSchemaSource;
- try {
- yangTextSchemaSource = context.getSourceProvider().getSource(sourceId).get();
- } catch (InterruptedException | ExecutionException e) {
- throw new WebApplicationException("Unable to retrieve source from SourceProvider.", e);
- }
- yangTextSchemaSource.copyTo(entityStream);
- }
-}
+++ /dev/null
-/*
- * 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.md.sal.rest.schema;
-
-import java.io.OutputStream;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.ext.MessageBodyWriter;
-import javax.ws.rs.ext.Provider;
-import javax.xml.stream.XMLStreamException;
-import org.opendaylight.restconf.common.schema.SchemaExportContext;
-import org.opendaylight.yangtools.yang.common.YangConstants;
-import org.opendaylight.yangtools.yang.model.export.YinExportUtils;
-
-@Provider
-@Produces({ YangConstants.RFC6020_YIN_MEDIA_TYPE })
-public class SchemaExportContentYinBodyWriter implements MessageBodyWriter<SchemaExportContext> {
-
- @Override
- public boolean isWriteable(final Class<?> type, final Type genericType, final Annotation[] annotations,
- final MediaType mediaType) {
- return type.equals(SchemaExportContext.class);
- }
-
- @Override
- public long getSize(final SchemaExportContext context, final Class<?> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType) {
- return -1;
- }
-
- @Override
- public void writeTo(final SchemaExportContext context, final Class<?> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType,
- final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream) throws
- WebApplicationException {
- try {
- YinExportUtils.writeModuleAsYinText(context.getModule(), entityStream);
- } catch (final XMLStreamException e) {
- throw new IllegalStateException(e);
- }
- }
-}
+++ /dev/null
-/*
- * 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.md.sal.rest.schema;
-
-import com.google.common.annotations.Beta;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import org.opendaylight.restconf.common.schema.SchemaExportContext;
-import org.opendaylight.yangtools.yang.common.YangConstants;
-
-/**
- * Retrieval of the YANG modules which server supports.
- *
- * @deprecated do not use this api. It is replaced by RestconfSchemaService
- */
-@Deprecated
-@Beta
-public interface SchemaRetrievalService {
- @GET
- @Produces({YangConstants.RFC6020_YIN_MEDIA_TYPE, YangConstants.RFC6020_YANG_MEDIA_TYPE})
- @Path("/modules/module/{identifier:.+}/schema")
- SchemaExportContext getSchema(@PathParam("identifier") String mountAndModuleId);
-}
+++ /dev/null
-/*
- * 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.md.sal.rest.schema;
-
-import com.google.common.base.Splitter;
-import com.google.common.collect.Iterables;
-import java.time.format.DateTimeParseException;
-import java.util.Iterator;
-import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.schema.SchemaExportContext;
-import org.opendaylight.restconf.common.validation.RestconfValidationUtils;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.common.ErrorType;
-import org.opendaylight.yangtools.yang.common.Revision;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-public class SchemaRetrievalServiceImpl implements SchemaRetrievalService {
-
- private final ControllerContext salContext;
-
- private static final Splitter SLASH_SPLITTER = Splitter.on("/");
- private static final String MOUNT_ARG = ControllerContext.MOUNT;
-
- public SchemaRetrievalServiceImpl(final ControllerContext controllerContext) {
- salContext = controllerContext;
- }
-
-
- @Override
- public SchemaExportContext getSchema(final String mountAndModule) {
- final SchemaContext schemaContext;
- final Iterable<String> pathComponents = SLASH_SPLITTER.split(mountAndModule);
- final Iterator<String> componentIter = pathComponents.iterator();
- if (!Iterables.contains(pathComponents, MOUNT_ARG)) {
- schemaContext = salContext.getGlobalSchema();
- } else {
- final StringBuilder pathBuilder = new StringBuilder();
- while (componentIter.hasNext()) {
- final String current = componentIter.next();
- // It is argument, not last element.
- if (pathBuilder.length() != 0) {
- pathBuilder.append("/");
- }
- pathBuilder.append(current);
- if (MOUNT_ARG.equals(current)) {
- // We stop right at mountpoint, last two arguments should
- // be module name and revision
- break;
- }
- }
- schemaContext = getMountSchemaContext(pathBuilder.toString());
-
- }
-
- RestconfDocumentedException.throwIf(!componentIter.hasNext(), "Module name must be supplied.",
- ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- final String moduleName = componentIter.next();
- RestconfDocumentedException.throwIf(!componentIter.hasNext(), "Revision date must be supplied.",
- ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- final String revisionString = componentIter.next();
- return getExportUsingNameAndRevision(schemaContext, moduleName, revisionString,
- salContext.getYangTextSourceProvider());
- }
-
- private static SchemaExportContext getExportUsingNameAndRevision(final SchemaContext schemaContext,
- final String moduleName, final String revisionStr,
- final DOMYangTextSourceProvider yangTextSourceProvider) {
- try {
- final Module module = schemaContext.findModule(moduleName, Revision.of(revisionStr)).orElse(null);
- return new SchemaExportContext(
- schemaContext, RestconfValidationUtils.checkNotNullDocumented(module, moduleName),
- yangTextSourceProvider);
- } catch (final DateTimeParseException e) {
- throw new RestconfDocumentedException("Supplied revision is not in expected date format YYYY-mm-dd", e);
- }
- }
-
- private SchemaContext getMountSchemaContext(final String identifier) {
- final InstanceIdentifierContext mountContext = salContext.toMountPointIdentifier(identifier);
- return mountContext.getSchemaContext();
- }
-}
-
+++ /dev/null
-/*
- * 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.sal.rest.api;
-
-import org.opendaylight.yangtools.yang.common.QName;
-
-/**
- * Base Draft for Restconf project.
- *
- * @deprecated Do not use old implementation of restconf draft. It will be replaced by Rfc8040.
- */
-@Deprecated
-public class Draft02 {
- public interface MediaTypes {
- String API = "application/yang.api";
- String DATASTORE = "application/yang.datastore";
- String DATA = "application/yang.data";
- String OPERATION = "application/yang.operation";
- String PATCH = "application/yang.patch";
- String PATCH_STATUS = "application/yang.patch-status";
- String STREAM = "application/yang.stream";
- }
-
- public interface RestConfModule {
- String REVISION = "2013-10-19";
-
- String NAME = "ietf-restconf";
-
- String NAMESPACE = "urn:ietf:params:xml:ns:yang:ietf-restconf";
-
- String RESTCONF_GROUPING_SCHEMA_NODE = "restconf";
-
- String RESTCONF_CONTAINER_SCHEMA_NODE = "restconf";
-
- String MODULES_CONTAINER_SCHEMA_NODE = "modules";
-
- String MODULE_LIST_SCHEMA_NODE = "module";
-
- String STREAMS_CONTAINER_SCHEMA_NODE = "streams";
-
- String STREAM_LIST_SCHEMA_NODE = "stream";
-
- String ERROR_LIST_SCHEMA_NODE = "error";
-
- QName IETF_RESTCONF_QNAME = QName.create(Draft02.RestConfModule.NAMESPACE, Draft02.RestConfModule.REVISION,
- Draft02.RestConfModule.NAME);
-
- QName ERRORS_QNAME = QName.create(IETF_RESTCONF_QNAME, "errors");
-
- QName ERROR_LIST_QNAME = QName.create(IETF_RESTCONF_QNAME, ERROR_LIST_SCHEMA_NODE);
-
- QName ERROR_TYPE_QNAME = QName.create(IETF_RESTCONF_QNAME, "error-type");
-
- QName ERROR_TAG_QNAME = QName.create(IETF_RESTCONF_QNAME, "error-tag");
-
- QName ERROR_APP_TAG_QNAME = QName.create(IETF_RESTCONF_QNAME, "error-app-tag");
-
- QName ERROR_MESSAGE_QNAME = QName.create(IETF_RESTCONF_QNAME, "error-message");
-
- QName ERROR_INFO_QNAME = QName.create(IETF_RESTCONF_QNAME, "error-info");
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 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.sal.rest.api;
-
-/*
- * This is a simple dummy interface to allow us to create instances of RestconfProvider
- * via the config subsystem.
- */
-public interface RestConnector {
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 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.sal.rest.api;
-
-public interface RestconfConstants {
-
- String IDENTIFIER = "identifier";
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.sal.rest.api;
-
-import java.io.Closeable;
-import java.io.Flushable;
-import java.io.IOException;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-public interface RestconfNormalizedNodeWriter extends Flushable, Closeable {
-
- RestconfNormalizedNodeWriter write(NormalizedNode node) throws IOException;
-}
+++ /dev/null
-/*
- * 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
- */
-package org.opendaylight.netconf.sal.rest.api;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.Encoded;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-import org.opendaylight.netconf.sal.rest.api.Draft02.MediaTypes;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.restconf.common.patch.Patch;
-import org.opendaylight.restconf.common.patch.PatchContext;
-import org.opendaylight.restconf.common.patch.PatchStatusContext;
-
-/**
- * The URI hierarchy for the RESTCONF resources consists of an entry point
- * container, 4 top-level resources, and 1 field.
- * <ul>
- * <li><b>/restconf</b> - {@link #getRoot()}
- * <ul>
- * <li><b>/config</b> - {@link #readConfigurationData(String, UriInfo)}
- * {@link #updateConfigurationData(String, NormalizedNodeContext, UriInfo)}
- * {@link #createConfigurationData(NormalizedNodeContext, UriInfo)}
- * {@link #createConfigurationData(String, NormalizedNodeContext, UriInfo)}
- * {@link #deleteConfigurationData(String)}
- * <li><b>/operational</b> - {@link #readOperationalData(String, UriInfo)}
- * <li>/modules - {@link #getModules(UriInfo)}
- * <ul>
- * <li>/module
- * </ul>
- * <li><b>/operations</b> -
- * {@link #invokeRpc(String, NormalizedNodeContext, UriInfo)}
- * {@link #invokeRpc(String, NormalizedNodeContext, UriInfo)}
- * <li>/version (field)
- * </ul>
- * </ul>
- */
-@Path("/")
-public interface RestconfService {
-
- String XML = "+xml";
- String JSON = "+json";
-
- @GET
- Object getRoot();
-
- /**
- * Get all modules supported by controller.
- *
- * @param uriInfo
- * URI info
- * @return {@link NormalizedNodeContext}
- * @deprecated do not use this method. It will be replaced by RestconfDataService#readData(UriInfo)
- */
- @Deprecated
- @GET
- @Path("/modules")
- @Produces({
- Draft02.MediaTypes.API + JSON,
- Draft02.MediaTypes.API + XML,
- MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML,
- MediaType.TEXT_XML
- })
- NormalizedNodeContext getModules(@Context UriInfo uriInfo);
-
- /**
- * Get all modules supported by mount point.
- *
- * @param identifier
- * mount point identifier
- * @param uriInfo
- * URI info
- * @return {@link NormalizedNodeContext}
- * @deprecated do not use this method. It will be replaced by RestconfDataService#readData(String,
- * UriInfo)
- */
- @Deprecated
- @GET
- @Path("/modules/{identifier:.+}")
- @Produces({
- Draft02.MediaTypes.API + JSON,
- Draft02.MediaTypes.API + XML,
- MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML,
- MediaType.TEXT_XML
- })
- NormalizedNodeContext getModules(@PathParam("identifier") String identifier, @Context UriInfo uriInfo);
-
- /**
- * Get module.
- *
- * @param identifier
- * path to target
- * @param uriInfo
- * URI info
- * @return {@link NormalizedNodeContext}
- * @deprecated do not use this method. It will be replaced by RestconfDataService#readData(String,
- * UriInfo)
- */
- @Deprecated
- @GET
- @Path("/modules/module/{identifier:.+}")
- @Produces({
- Draft02.MediaTypes.API + JSON,
- Draft02.MediaTypes.API + XML,
- MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML,
- MediaType.TEXT_XML
- })
- NormalizedNodeContext getModule(@PathParam("identifier") String identifier, @Context UriInfo uriInfo);
-
- /**
- * List of rpc or action operations supported by the server.
- *
- * @return A JSON document string
- * @deprecated do not use this method. It will be replaced by
- * RestconfOperationsService#getOperations(UriInfo)
- */
- @Deprecated
- @GET
- @Path("/operations")
- @Produces({ Draft02.MediaTypes.API + JSON, MediaType.APPLICATION_JSON })
- String getOperationsJSON();
-
- /**
- * List of rpc or action operations supported by the server.
- *
- * @return A XML document string
- * @deprecated do not use this method. It will be replaced by
- * RestconfOperationsService#getOperations(UriInfo)
- */
- @Deprecated
- @GET
- @Path("/operations")
- @Produces({ Draft02.MediaTypes.API + XML, MediaType.APPLICATION_XML, MediaType.TEXT_XML })
- String getOperationsXML();
-
- /**
- * Valid for mount points. List of operations supported by the server.
- *
- * @param identifier
- * path parameter
- * @param uriInfo
- * URI information
- * @return {@link NormalizedNodeContext}
- * @deprecated do not use this method. It will be replaced by
- * RestconfOperationsService#getOperations(String, UriInfo)
- */
- @Deprecated
- @GET
- @Path("/operations/{identifier:.+}")
- @Produces({
- Draft02.MediaTypes.API + JSON,
- Draft02.MediaTypes.API + XML,
- MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML,
- MediaType.TEXT_XML
- })
- NormalizedNodeContext getOperations(@PathParam("identifier") String identifier, @Context UriInfo uriInfo);
-
- /**
- * Invoke RPC operation.
- *
- * @param identifier
- * module name and rpc identifier string for the desired operation
- * @param payload
- * {@link NormalizedNodeContext} - the body of the operation
- * @param uriInfo
- * URI info
- * @return {@link NormalizedNodeContext}
- * @deprecated do not use this method. It will be replaced by
- * RestconfInvokeOperationsService#invokeRpc(String, NormalizedNodeContext, UriInfo)
- */
- @Deprecated
- @POST
- @Path("/operations/{identifier:.+}")
- @Produces({
- Draft02.MediaTypes.OPERATION + JSON,
- Draft02.MediaTypes.OPERATION + XML,
- Draft02.MediaTypes.DATA + JSON,
- Draft02.MediaTypes.DATA + XML,
- MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML,
- MediaType.TEXT_XML
- })
- @Consumes({
- Draft02.MediaTypes.OPERATION + JSON,
- Draft02.MediaTypes.OPERATION + XML,
- Draft02.MediaTypes.DATA + JSON,
- Draft02.MediaTypes.DATA + XML,
- MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML,
- MediaType.TEXT_XML
- })
- NormalizedNodeContext invokeRpc(@Encoded @PathParam("identifier") String identifier, NormalizedNodeContext payload,
- @Context UriInfo uriInfo);
-
- /**
- * Get target data resource from config data store.
- *
- * @param identifier
- * path to target
- * @param uriInfo
- * URI info
- * @return {@link NormalizedNodeContext}
- * @deprecated do not use this method. It will be replaced by RestconfDataService#readData(String,
- * UriInfo)
- */
- @Deprecated
- @GET
- @Path("/config/{identifier:.+}")
- @Produces({
- Draft02.MediaTypes.DATA + JSON,
- Draft02.MediaTypes.DATA + XML,
- MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML,
- MediaType.TEXT_XML
- })
- NormalizedNodeContext readConfigurationData(@Encoded @PathParam("identifier") String identifier,
- @Context UriInfo uriInfo);
-
- /**
- * Get target data resource from operational data store.
- *
- * @param identifier
- * path to target
- * @param uriInfo
- * URI info
- * @return {@link NormalizedNodeContext}
- * @deprecated do not use this method. It will be replaced by RestconfDataService#readData(String,
- * UriInfo)
- */
- @Deprecated
- @GET
- @Path("/operational/{identifier:.+}")
- @Produces({
- Draft02.MediaTypes.DATA + JSON,
- Draft02.MediaTypes.DATA + XML,
- MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML,
- MediaType.TEXT_XML
- })
- NormalizedNodeContext readOperationalData(@Encoded @PathParam("identifier") String identifier,
- @Context UriInfo uriInfo);
-
- /**
- * Create or replace the target data resource.
- *
- * @param identifier
- * path to target
- * @param payload
- * data node for put to config DS
- * @return {@link Response}
- * @deprecated do not use this method. It will be replaced by RestconfDataService#putData(String,
- * NormalizedNodeContext, UriInfo)
- */
- @Deprecated
- @PUT
- @Path("/config/{identifier:.+}")
- @Consumes({
- Draft02.MediaTypes.DATA + JSON,
- Draft02.MediaTypes.DATA + XML,
- MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML,
- MediaType.TEXT_XML
- })
- Response updateConfigurationData(@Encoded @PathParam("identifier") String identifier,
- NormalizedNodeContext payload, @Context UriInfo uriInfo);
-
- /**
- * Create a data resource in target.
- *
- * @param identifier
- * path to target
- * @param payload
- * new data
- * @param uriInfo
- * URI info
- * @return {@link Response}
- * @deprecated do not use this method. It will be replaced by RestconfDataService#postData(String,
- * NormalizedNodeContext, UriInfo)
- */
- @Deprecated
- @POST
- @Path("/config/{identifier:.+}")
- @Consumes({
- Draft02.MediaTypes.DATA + JSON,
- Draft02.MediaTypes.DATA + XML,
- MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML,
- MediaType.TEXT_XML
- })
- Response createConfigurationData(@Encoded @PathParam("identifier") String identifier, NormalizedNodeContext payload,
- @Context UriInfo uriInfo);
-
- /**
- * Create a data resource.
- *
- * @param payload
- * new data
- * @param uriInfo
- * URI info
- * @return {@link Response}
- * @deprecated do not use this method. It will be replaced by
- * RestconfDataService#postData(NormalizedNodeContext, UriInfo)
- */
- @Deprecated
- @POST
- @Path("/config")
- @Consumes({
- Draft02.MediaTypes.DATA + JSON,
- Draft02.MediaTypes.DATA + XML,
- MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML,
- MediaType.TEXT_XML
- })
- Response createConfigurationData(NormalizedNodeContext payload, @Context UriInfo uriInfo);
-
- /**
- * Delete the target data resource.
- *
- * @param identifier
- * path to target
- * @return {@link Response}
- * @deprecated do not use this method. It will be replaced by RestconfDataService#deleteData(String)
- */
- @Deprecated
- @DELETE
- @Path("/config/{identifier:.+}")
- Response deleteConfigurationData(@Encoded @PathParam("identifier") String identifier);
-
- /**
- * Subscribe to stream.
- *
- * @param identifier
- * stream identifier
- * @param uriInfo
- * URI info
- * @return {@link NormalizedNodeContext}
- * @deprecated do not use this method. It will be replaced by
- * RestconfStreamsSubscriptionService#subscribeToStream(String, UriInfo)
- */
- @Deprecated
- @GET
- @Path("/streams/stream/{identifier:.+}")
- NormalizedNodeContext subscribeToStream(@Encoded @PathParam("identifier") String identifier,
- @Context UriInfo uriInfo);
-
- /**
- * Get list of all streams.
- *
- * @param uriInfo
- * URI info
- * @return {@link NormalizedNodeContext}
- * @deprecated do not use this method. It will be replaced by RestconfDataService#readData(String,
- * UriInfo)
- **/
- @Deprecated
- @GET
- @Path("/streams")
- @Produces({
- Draft02.MediaTypes.API + JSON,
- Draft02.MediaTypes.API + XML,
- MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML,
- MediaType.TEXT_XML
- })
- NormalizedNodeContext getAvailableStreams(@Context UriInfo uriInfo);
-
- /**
- * Ordered list of edits that are applied to the target datastore by the server.
- *
- * @param identifier
- * path to target
- * @param context
- * edits
- * @param uriInfo
- * URI info
- * @return {@link PatchStatusContext}
- * @deprecated do not use this method. It will be replaced by RestconfDataService#patchData(String,
- * PatchContext, UriInfo)
- */
- @Deprecated
- @Patch
- @Path("/config/{identifier:.+}")
- @Consumes({
- MediaTypes.PATCH + JSON,
- MediaTypes.PATCH + XML
- })
- @Produces({
- MediaTypes.PATCH_STATUS + JSON,
- MediaTypes.PATCH_STATUS + XML
- })
- PatchStatusContext patchConfigurationData(@Encoded @PathParam("identifier") String identifier, PatchContext
- context, @Context UriInfo uriInfo);
-
- /**
- * Ordered list of edits that are applied to the datastore by the server.
- *
- * @param context
- * edits
- * @param uriInfo
- * URI info
- * @return {@link PatchStatusContext}
- * @deprecated do not use this method. It will be replaced by RestconfDataService#patchData(PatchContext,
- * UriInfo)
- */
- @Deprecated
- @Patch
- @Path("/config")
- @Consumes({
- MediaTypes.PATCH + JSON,
- MediaTypes.PATCH + XML
- })
- @Produces({
- MediaTypes.PATCH_STATUS + JSON,
- MediaTypes.PATCH_STATUS + XML
- })
- PatchStatusContext patchConfigurationData(PatchContext context, @Context UriInfo uriInfo);
-}
+++ /dev/null
-/*
- * 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.sal.rest.api;
-
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 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.sal.rest.impl;
-
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.Request;
-import javax.ws.rs.core.UriInfo;
-import org.opendaylight.netconf.sal.rest.api.RestconfConstants;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-
-/**
- * JAX-RS Provider.
- *
- * @deprecated This class will be replaced by AbstractIdentifierAwareJaxRsProvider in restconf-nb-rfc8040
- */
-@Deprecated
-public class AbstractIdentifierAwareJaxRsProvider {
-
- private static final String POST = "POST";
-
- @Context
- private UriInfo uriInfo;
-
- @Context
- private Request request;
-
- private final ControllerContext controllerContext;
-
- protected AbstractIdentifierAwareJaxRsProvider(final ControllerContext controllerContext) {
- this.controllerContext = controllerContext;
- }
-
- protected final String getIdentifier() {
- return uriInfo.getPathParameters(false).getFirst(RestconfConstants.IDENTIFIER);
- }
-
- protected InstanceIdentifierContext getInstanceIdentifierContext() {
- return controllerContext.toInstanceIdentifier(getIdentifier());
- }
-
- protected UriInfo getUriInfo() {
- return uriInfo;
- }
-
- protected boolean isPost() {
- return POST.equals(request.getMethod());
- }
-
- protected ControllerContext getControllerContext() {
- return controllerContext;
- }
-
- Request getRequest() {
- return request;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.sal.rest.impl;
-
-import static java.util.Objects.requireNonNull;
-import static org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter.UNKNOWN_SIZE;
-
-import com.google.common.collect.Iterables;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Map.Entry;
-import java.util.Optional;
-import java.util.Set;
-import javax.xml.transform.dom.DOMSource;
-import org.opendaylight.netconf.sal.rest.api.RestconfNormalizedNodeWriter;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.AnyxmlNode;
-import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UserLeafSetNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UserMapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This is an experimental iterator over a {@link NormalizedNode}. This is essentially the opposite of a
- * {@link javax.xml.stream.XMLStreamReader} -- unlike instantiating an iterator over the backing data, this
- * encapsulates a {@link NormalizedNodeStreamWriter} and allows us to write multiple nodes.
- *
- * @deprecated This class will be replaced by ParameterAwareNormalizedNodeWriter in restconf-nb-rfc8040
- */
-@Deprecated
-public class DepthAwareNormalizedNodeWriter implements RestconfNormalizedNodeWriter {
- private final NormalizedNodeStreamWriter writer;
- protected int currentDepth = 0;
- protected final int maxDepth;
-
- private DepthAwareNormalizedNodeWriter(final NormalizedNodeStreamWriter writer, final int maxDepth) {
- this.writer = requireNonNull(writer);
- this.maxDepth = maxDepth;
- }
-
- protected final NormalizedNodeStreamWriter getWriter() {
- return writer;
- }
-
- /**
- * Create a new writer backed by a {@link NormalizedNodeStreamWriter}.
- *
- * @param writer Back-end writer
- * @return A new instance.
- */
- public static DepthAwareNormalizedNodeWriter forStreamWriter(final NormalizedNodeStreamWriter writer,
- final int maxDepth) {
- return forStreamWriter(writer, true, maxDepth);
- }
-
- /**
- * Create a new writer backed by a {@link NormalizedNodeStreamWriter}.
- * Unlike the simple {@link #forStreamWriter(NormalizedNodeStreamWriter, int)}
- * method, this allows the caller to switch off RFC6020 XML compliance, providing better
- * throughput. The reason is that the XML mapping rules in RFC6020 require the encoding
- * to emit leaf nodes which participate in a list's key first and in the order in which
- * they are defined in the key. For JSON, this requirement is completely relaxed and leaves
- * can be ordered in any way we see fit. The former requires a bit of work: first a lookup
- * for each key and then for each emitted node we need to check whether it was already
- * emitted.
- *
- * @param writer Back-end writer
- * @param orderKeyLeaves whether the returned instance should be RFC6020 XML compliant.
- * @return A new instance.
- */
- public static DepthAwareNormalizedNodeWriter forStreamWriter(final NormalizedNodeStreamWriter writer,
- final boolean orderKeyLeaves, final int maxDepth) {
- return orderKeyLeaves ? new OrderedDepthAwareNormalizedNodeWriter(writer, maxDepth)
- : new DepthAwareNormalizedNodeWriter(writer, maxDepth);
- }
-
- /**
- * Iterate over the provided {@link NormalizedNode} and emit write
- * events to the encapsulated {@link NormalizedNodeStreamWriter}.
- *
- * @param node Node
- * @return DepthAwareNormalizedNodeWriter
- * @throws IOException when thrown from the backing writer.
- */
- @Override
- public final DepthAwareNormalizedNodeWriter write(final NormalizedNode node) throws IOException {
- if (wasProcessedAsCompositeNode(node)) {
- return this;
- }
-
- if (wasProcessAsSimpleNode(node)) {
- return this;
- }
-
- throw new IllegalStateException("It wasn't possible to serialize node " + node);
- }
-
- @Override
- public void flush() throws IOException {
- writer.flush();
- }
-
- @Override
- public void close() throws IOException {
- writer.flush();
- writer.close();
- }
-
- /**
- * Emit a best guess of a hint for a particular set of children. It evaluates the
- * iterable to see if the size can be easily gotten to. If it is, we hint at the
- * real number of child nodes. Otherwise we emit UNKNOWN_SIZE.
- *
- * @param children Child nodes
- * @return Best estimate of the collection size required to hold all the children.
- */
- static final int childSizeHint(final Iterable<?> children) {
- return children instanceof Collection ? ((Collection<?>) children).size() : UNKNOWN_SIZE;
- }
-
- private boolean wasProcessAsSimpleNode(final NormalizedNode node) throws IOException {
- if (node instanceof LeafSetEntryNode) {
- if (currentDepth < maxDepth) {
- final LeafSetEntryNode<?> nodeAsLeafList = (LeafSetEntryNode<?>) node;
- writer.startLeafSetEntryNode(nodeAsLeafList.getIdentifier());
- writer.scalarValue(nodeAsLeafList.body());
- writer.endNode();
- }
- return true;
- } else if (node instanceof LeafNode) {
- final LeafNode<?> nodeAsLeaf = (LeafNode<?>)node;
- writer.startLeafNode(nodeAsLeaf.getIdentifier());
- writer.scalarValue(nodeAsLeaf.body());
- writer.endNode();
- return true;
- } else if (node instanceof AnyxmlNode) {
- final AnyxmlNode<?> anyxmlNode = (AnyxmlNode<?>)node;
- final Class<?> objectModel = anyxmlNode.bodyObjectModel();
- if (writer.startAnyxmlNode(anyxmlNode.getIdentifier(), objectModel)) {
- if (DOMSource.class.isAssignableFrom(objectModel)) {
- writer.domSourceValue((DOMSource) anyxmlNode.body());
- } else {
- writer.scalarValue(anyxmlNode.body());
- }
- writer.endNode();
- }
- return true;
- }
-
- return false;
- }
-
- /**
- * Emit events for all children and then emit an endNode() event.
- *
- * @param children Child iterable
- * @return True
- * @throws IOException when the writer reports it
- */
- protected final boolean writeChildren(final Iterable<? extends NormalizedNode> children) throws IOException {
- if (currentDepth < maxDepth) {
- for (final NormalizedNode child : children) {
- write(child);
- }
- }
- writer.endNode();
- return true;
- }
-
- protected boolean writeMapEntryChildren(final MapEntryNode mapEntryNode) throws IOException {
- if (currentDepth < maxDepth) {
- writeChildren(mapEntryNode.body());
- } else if (currentDepth == maxDepth) {
- writeOnlyKeys(mapEntryNode.getIdentifier().entrySet());
- }
- return true;
- }
-
- private void writeOnlyKeys(final Set<Entry<QName, Object>> entries) throws IOException {
- for (final Entry<QName, Object> entry : entries) {
- writer.startLeafNode(new NodeIdentifier(entry.getKey()));
- writer.scalarValue(entry.getValue());
- writer.endNode();
- }
- writer.endNode();
- }
-
- protected boolean writeMapEntryNode(final MapEntryNode node) throws IOException {
- writer.startMapEntryNode(node.getIdentifier(), childSizeHint(node.body()));
- currentDepth++;
- writeMapEntryChildren(node);
- currentDepth--;
- return true;
- }
-
- private boolean wasProcessedAsCompositeNode(final NormalizedNode node) throws IOException {
- boolean processedAsCompositeNode = false;
- if (node instanceof ContainerNode) {
- final ContainerNode n = (ContainerNode) node;
- writer.startContainerNode(n.getIdentifier(), childSizeHint(n.body()));
- currentDepth++;
- processedAsCompositeNode = writeChildren(n.body());
- currentDepth--;
- } else if (node instanceof MapEntryNode) {
- processedAsCompositeNode = writeMapEntryNode((MapEntryNode) node);
- } else if (node instanceof UnkeyedListEntryNode) {
- final UnkeyedListEntryNode n = (UnkeyedListEntryNode) node;
- writer.startUnkeyedListItem(n.getIdentifier(), childSizeHint(n.body()));
- currentDepth++;
- processedAsCompositeNode = writeChildren(n.body());
- currentDepth--;
- } else if (node instanceof ChoiceNode) {
- final ChoiceNode n = (ChoiceNode) node;
- writer.startChoiceNode(n.getIdentifier(), childSizeHint(n.body()));
- processedAsCompositeNode = writeChildren(n.body());
- } else if (node instanceof AugmentationNode) {
- final AugmentationNode n = (AugmentationNode) node;
- writer.startAugmentationNode(n.getIdentifier());
- processedAsCompositeNode = writeChildren(n.body());
- } else if (node instanceof UnkeyedListNode) {
- final UnkeyedListNode n = (UnkeyedListNode) node;
- writer.startUnkeyedList(n.getIdentifier(), childSizeHint(n.body()));
- processedAsCompositeNode = writeChildren(n.body());
- } else if (node instanceof UserMapNode) {
- final UserMapNode n = (UserMapNode) node;
- writer.startOrderedMapNode(n.getIdentifier(), childSizeHint(n.body()));
- processedAsCompositeNode = writeChildren(n.body());
- } else if (node instanceof MapNode) {
- final MapNode n = (MapNode) node;
- writer.startMapNode(n.getIdentifier(), childSizeHint(n.body()));
- processedAsCompositeNode = writeChildren(n.body());
- } else if (node instanceof LeafSetNode) {
- final LeafSetNode<?> n = (LeafSetNode<?>) node;
- if (node instanceof UserLeafSetNode) {
- writer.startOrderedLeafSet(n.getIdentifier(), childSizeHint(n.body()));
- } else {
- writer.startLeafSet(n.getIdentifier(), childSizeHint(n.body()));
- }
- currentDepth++;
- processedAsCompositeNode = writeChildren(n.body());
- currentDepth--;
- }
-
- return processedAsCompositeNode;
- }
-
- private static final class OrderedDepthAwareNormalizedNodeWriter extends DepthAwareNormalizedNodeWriter {
- private static final Logger LOG = LoggerFactory.getLogger(OrderedDepthAwareNormalizedNodeWriter.class);
-
- OrderedDepthAwareNormalizedNodeWriter(final NormalizedNodeStreamWriter writer, final int maxDepth) {
- super(writer, maxDepth);
- }
-
- @Override
- protected boolean writeMapEntryNode(final MapEntryNode node) throws IOException {
- final NormalizedNodeStreamWriter writer = getWriter();
- writer.startMapEntryNode(node.getIdentifier(), childSizeHint(node.body()));
-
- final Set<QName> qnames = node.getIdentifier().keySet();
- // Write out all the key children
- for (final QName qname : qnames) {
- final Optional<? extends NormalizedNode> child = node.findChildByArg(new NodeIdentifier(qname));
- if (child.isPresent()) {
- write(child.get());
- } else {
- LOG.info("No child for key element {} found", qname);
- }
- }
-
- // Write all the rest
- currentDepth++;
- final boolean result = writeChildren(Iterables.filter(node.body(), input -> {
- if (input instanceof AugmentationNode) {
- return true;
- }
- if (!qnames.contains(input.getIdentifier().getNodeType())) {
- return true;
- }
-
- LOG.debug("Skipping key child {}", input);
- return false;
- }));
- currentDepth--;
- return result;
- }
- }
-}
+++ /dev/null
-/*
- * 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.sal.rest.impl;
-
-import com.google.common.base.Throwables;
-import com.google.common.collect.Iterables;
-import com.google.gson.stream.JsonReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.ext.MessageBodyReader;
-import javax.ws.rs.ext.Provider;
-import org.opendaylight.netconf.sal.rest.api.Draft02;
-import org.opendaylight.netconf.sal.rest.api.RestconfService;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.util.RestUtil;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.common.ErrorType;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier;
-import org.opendaylight.yangtools.yang.data.codec.gson.JsonParserStream;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
-import org.opendaylight.yangtools.yang.data.impl.schema.ResultAlreadySetException;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Provider
-@Consumes({
- Draft02.MediaTypes.DATA + RestconfService.JSON,
- Draft02.MediaTypes.OPERATION + RestconfService.JSON,
- MediaType.APPLICATION_JSON
-})
-public class JsonNormalizedNodeBodyReader
- extends AbstractIdentifierAwareJaxRsProvider implements MessageBodyReader<NormalizedNodeContext> {
-
- private static final Logger LOG = LoggerFactory.getLogger(JsonNormalizedNodeBodyReader.class);
-
- public JsonNormalizedNodeBodyReader(final ControllerContext controllerContext) {
- super(controllerContext);
- }
-
- @Override
- public boolean isReadable(final Class<?> type, final Type genericType, final Annotation[] annotations,
- final MediaType mediaType) {
- return true;
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- @Override
- public NormalizedNodeContext readFrom(final Class<NormalizedNodeContext> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType,
- final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream) throws
- WebApplicationException {
- try {
- return readFrom(getInstanceIdentifierContext(), entityStream, isPost());
- } catch (final Exception e) {
- propagateExceptionAs(e);
- return null; // no-op
- }
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- public static NormalizedNodeContext readFrom(final String uriPath, final InputStream entityStream,
- final boolean isPost, final ControllerContext controllerContext) throws RestconfDocumentedException {
-
- try {
- return readFrom(controllerContext.toInstanceIdentifier(uriPath), entityStream, isPost);
- } catch (final Exception e) {
- propagateExceptionAs(e);
- return null; // no-op
- }
- }
-
- private static NormalizedNodeContext readFrom(final InstanceIdentifierContext path,
- final InputStream entityStream, final boolean isPost)
- throws IOException {
- final Optional<InputStream> nonEmptyInputStreamOptional = RestUtil.isInputStreamEmpty(entityStream);
- if (nonEmptyInputStreamOptional.isEmpty()) {
- return new NormalizedNodeContext(path, null);
- }
- final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
- final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
-
- final Inference parentInference;
- if (isPost && !(path.getSchemaNode() instanceof RpcDefinition)) {
- parentInference = path.inference();
- } else {
- final var inference = path.inference();
- if (!inference.statementPath().isEmpty()) {
- final var stack = inference.toSchemaInferenceStack();
- stack.exit();
- parentInference = stack.toInference();
- } else {
- parentInference = inference;
- }
- }
-
- final JsonParserStream jsonParser = JsonParserStream.create(writer,
- JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02.getShared(path.getSchemaContext()),
- parentInference);
- final JsonReader reader = new JsonReader(new InputStreamReader(nonEmptyInputStreamOptional.get(),
- StandardCharsets.UTF_8));
- jsonParser.parse(reader);
-
- NormalizedNode result = resultHolder.getResult();
- final List<YangInstanceIdentifier.PathArgument> iiToDataList = new ArrayList<>();
- InstanceIdentifierContext newIIContext;
-
- while (result instanceof AugmentationNode || result instanceof ChoiceNode) {
- final Object childNode = ((DataContainerNode) result).body().iterator().next();
- if (isPost) {
- iiToDataList.add(result.getIdentifier());
- }
- result = (NormalizedNode) childNode;
- }
-
- if (isPost) {
- if (result instanceof MapEntryNode) {
- iiToDataList.add(new YangInstanceIdentifier.NodeIdentifier(result.getIdentifier().getNodeType()));
- iiToDataList.add(result.getIdentifier());
- } else {
- iiToDataList.add(result.getIdentifier());
- }
- } else {
- if (result instanceof MapNode) {
- result = Iterables.getOnlyElement(((MapNode) result).body());
- }
- }
-
- return new NormalizedNodeContext(path.withConcatenatedArgs(iiToDataList), result);
- }
-
- private static void propagateExceptionAs(final Exception exception) throws RestconfDocumentedException {
- Throwables.throwIfInstanceOf(exception, RestconfDocumentedException.class);
- LOG.debug("Error parsing json input", exception);
-
- if (exception instanceof ResultAlreadySetException) {
- throw new RestconfDocumentedException("Error parsing json input: Failed to create new parse result data. "
- + "Are you creating multiple resources/subresources in POST request?", exception);
- }
-
- RestconfDocumentedException.throwIfYangError(exception);
- throw new RestconfDocumentedException("Error parsing input: " + exception.getMessage(), ErrorType.PROTOCOL,
- ErrorTag.MALFORMED_MESSAGE, exception);
- }
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2015 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.sal.rest.impl;
-
-import static com.google.common.base.Verify.verify;
-
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableList;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonToken;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.StringReader;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Optional;
-import java.util.concurrent.atomic.AtomicReference;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.ext.MessageBodyReader;
-import javax.ws.rs.ext.Provider;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.netconf.sal.rest.api.Draft02;
-import org.opendaylight.netconf.sal.rest.api.RestconfService;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.patch.PatchContext;
-import org.opendaylight.restconf.common.patch.PatchEditOperation;
-import org.opendaylight.restconf.common.patch.PatchEntity;
-import org.opendaylight.restconf.common.util.RestUtil;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.common.ErrorType;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier;
-import org.opendaylight.yangtools.yang.data.codec.gson.JsonParserStream;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
-import org.opendaylight.yangtools.yang.data.impl.schema.ResultAlreadySetException;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Patch reader for JSON.
- *
- * @deprecated This class will be replaced by JsonToPatchBodyReader in restconf-nb-rfc8040
- */
-@Deprecated
-@Provider
-@Consumes({Draft02.MediaTypes.PATCH + RestconfService.JSON})
-public class JsonToPatchBodyReader extends AbstractIdentifierAwareJaxRsProvider
- implements MessageBodyReader<PatchContext> {
-
- private static final Logger LOG = LoggerFactory.getLogger(JsonToPatchBodyReader.class);
-
- public JsonToPatchBodyReader(final ControllerContext controllerContext) {
- super(controllerContext);
- }
-
- @Override
- public boolean isReadable(final Class<?> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType) {
- return true;
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- @Override
- public PatchContext readFrom(final Class<PatchContext> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType,
- final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream)
- throws WebApplicationException {
- try {
- return readFrom(getInstanceIdentifierContext(), entityStream);
- } catch (final Exception e) {
- throw propagateExceptionAs(e);
- }
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- public PatchContext readFrom(final String uriPath, final InputStream entityStream) throws
- RestconfDocumentedException {
- try {
- return readFrom(getControllerContext().toInstanceIdentifier(uriPath), entityStream);
- } catch (final Exception e) {
- propagateExceptionAs(e);
- return null; // no-op
- }
- }
-
- private PatchContext readFrom(final InstanceIdentifierContext path, final InputStream entityStream)
- throws IOException {
- final Optional<InputStream> nonEmptyInputStreamOptional = RestUtil.isInputStreamEmpty(entityStream);
- if (nonEmptyInputStreamOptional.isEmpty()) {
- return new PatchContext(path, null, null);
- }
-
- final JsonReader jsonReader = new JsonReader(new InputStreamReader(nonEmptyInputStreamOptional.get(),
- StandardCharsets.UTF_8));
- AtomicReference<String> patchId = new AtomicReference<>();
- final List<PatchEntity> resultList = read(jsonReader, path, patchId);
- jsonReader.close();
-
- return new PatchContext(path, resultList, patchId.get());
- }
-
- private static RuntimeException propagateExceptionAs(final Exception exception) throws RestconfDocumentedException {
- Throwables.throwIfInstanceOf(exception, RestconfDocumentedException.class);
- LOG.debug("Error parsing json input", exception);
-
- if (exception instanceof ResultAlreadySetException) {
- throw new RestconfDocumentedException("Error parsing json input: Failed to create new parse result data. ");
- }
-
- RestconfDocumentedException.throwIfYangError(exception);
- throw new RestconfDocumentedException("Error parsing json input: " + exception.getMessage(), ErrorType.PROTOCOL,
- ErrorTag.MALFORMED_MESSAGE, exception);
- }
-
- private List<PatchEntity> read(final JsonReader in, final InstanceIdentifierContext path,
- final AtomicReference<String> patchId) throws IOException {
- final List<PatchEntity> resultCollection = new ArrayList<>();
- final StringModuleInstanceIdentifierCodec codec = new StringModuleInstanceIdentifierCodec(
- path.getSchemaContext());
- final JsonToPatchBodyReader.PatchEdit edit = new JsonToPatchBodyReader.PatchEdit();
-
- while (in.hasNext()) {
- switch (in.peek()) {
- case STRING:
- case NUMBER:
- in.nextString();
- break;
- case BOOLEAN:
- Boolean.toString(in.nextBoolean());
- break;
- case NULL:
- in.nextNull();
- break;
- case BEGIN_ARRAY:
- in.beginArray();
- break;
- case BEGIN_OBJECT:
- in.beginObject();
- break;
- case END_DOCUMENT:
- break;
- case NAME:
- parseByName(in.nextName(), edit, in, path, codec, resultCollection, patchId);
- break;
- case END_OBJECT:
- in.endObject();
- break;
- case END_ARRAY:
- in.endArray();
- break;
-
- default:
- break;
- }
- }
-
- return ImmutableList.copyOf(resultCollection);
- }
-
- /**
- * Switch value of parsed JsonToken.NAME and read edit definition or patch id.
- *
- * @param name value of token
- * @param edit PatchEdit instance
- * @param in JsonReader reader
- * @param path InstanceIdentifierContext context
- * @param codec StringModuleInstanceIdentifierCodec codec
- * @param resultCollection collection of parsed edits
- * @throws IOException if operation fails
- */
- private void parseByName(final @NonNull String name, final @NonNull PatchEdit edit,
- final @NonNull JsonReader in, final @NonNull InstanceIdentifierContext path,
- final @NonNull StringModuleInstanceIdentifierCodec codec,
- final @NonNull List<PatchEntity> resultCollection,
- final @NonNull AtomicReference<String> patchId) throws IOException {
- switch (name) {
- case "edit" :
- if (in.peek() == JsonToken.BEGIN_ARRAY) {
- in.beginArray();
-
- while (in.hasNext()) {
- readEditDefinition(edit, in, path, codec);
- resultCollection.add(prepareEditOperation(edit));
- edit.clear();
- }
-
- in.endArray();
- } else {
- readEditDefinition(edit, in, path, codec);
- resultCollection.add(prepareEditOperation(edit));
- edit.clear();
- }
-
- break;
- case "patch-id" :
- patchId.set(in.nextString());
- break;
- default:
- break;
- }
- }
-
- /**
- * Read one patch edit object from Json input.
- * @param edit PatchEdit instance to be filled with read data
- * @param in JsonReader reader
- * @param path InstanceIdentifierContext path context
- * @param codec StringModuleInstanceIdentifierCodec codec
- * @throws IOException if operation fails
- */
- private void readEditDefinition(final @NonNull PatchEdit edit, final @NonNull JsonReader in,
- final @NonNull InstanceIdentifierContext path,
- final @NonNull StringModuleInstanceIdentifierCodec codec) throws IOException {
- final StringBuilder value = new StringBuilder();
- in.beginObject();
-
- while (in.hasNext()) {
- final String editDefinition = in.nextName();
- switch (editDefinition) {
- case "edit-id" :
- edit.setId(in.nextString());
- break;
- case "operation" :
- edit.setOperation(PatchEditOperation.valueOf(in.nextString().toUpperCase(Locale.ROOT)));
- break;
- case "target" :
- // target can be specified completely in request URI
- final String target = in.nextString();
- if (target.equals("/")) {
- edit.setTarget(path.getInstanceIdentifier());
- edit.setTargetSchemaNode(SchemaInferenceStack.of(path.getSchemaContext()).toInference());
- } else {
- edit.setTarget(codec.deserialize(codec.serialize(path.getInstanceIdentifier()).concat(target)));
-
- final var stack = codec.getDataContextTree().enterPath(edit.getTarget()).orElseThrow().stack();
- stack.exit();
- final EffectiveStatement<?, ?> parentStmt = stack.currentStatement();
- verify(parentStmt instanceof SchemaNode, "Unexpected parent %s", parentStmt);
- edit.setTargetSchemaNode(stack.toInference());
- }
-
- break;
- case "value" :
- // save data defined in value node for next (later) processing, because target needs to be read
- // always first and there is no ordering in Json input
- readValueNode(value, in);
- break;
- default:
- break;
- }
- }
-
- in.endObject();
-
- // read saved data to normalized node when target schema is already known
- edit.setData(readEditData(new JsonReader(
- new StringReader(value.toString())), edit.getTargetSchemaNode(), path));
- }
-
- /**
- * Parse data defined in value node and saves it to buffer.
- * @param value Buffer to read value node
- * @param in JsonReader reader
- * @throws IOException if operation fails
- */
- private void readValueNode(final @NonNull StringBuilder value, final @NonNull JsonReader in) throws IOException {
- in.beginObject();
- value.append('{');
-
- value.append('"').append(in.nextName()).append("\":");
-
- if (in.peek() == JsonToken.BEGIN_ARRAY) {
- in.beginArray();
- value.append('[');
-
- while (in.hasNext()) {
- if (in.peek() == JsonToken.STRING) {
- value.append('"').append(in.nextString()).append('"');
- } else {
- readValueObject(value, in);
- }
- if (in.peek() != JsonToken.END_ARRAY) {
- value.append(',');
- }
- }
-
- in.endArray();
- value.append(']');
- } else {
- readValueObject(value, in);
- }
-
- in.endObject();
- value.append('}');
- }
-
- /**
- * Parse one value object of data and saves it to buffer.
- * @param value Buffer to read value object
- * @param in JsonReader reader
- * @throws IOException if operation fails
- */
- private void readValueObject(final @NonNull StringBuilder value, final @NonNull JsonReader in) throws IOException {
- // read simple leaf value
- if (in.peek() == JsonToken.STRING) {
- value.append('"').append(in.nextString()).append('"');
- return;
- }
-
- in.beginObject();
- value.append('{');
-
- while (in.hasNext()) {
- value.append('"').append(in.nextName()).append("\":");
-
- if (in.peek() == JsonToken.STRING) {
- value.append('"').append(in.nextString()).append('"');
- } else {
- if (in.peek() == JsonToken.BEGIN_ARRAY) {
- in.beginArray();
- value.append('[');
-
- while (in.hasNext()) {
- if (in.peek() == JsonToken.STRING) {
- value.append('"').append(in.nextString()).append('"');
- } else {
- readValueObject(value, in);
- }
- if (in.peek() != JsonToken.END_ARRAY) {
- value.append(',');
- }
- }
-
- in.endArray();
- value.append(']');
- } else {
- readValueObject(value, in);
- }
- }
-
- if (in.peek() != JsonToken.END_OBJECT) {
- value.append(',');
- }
- }
-
- in.endObject();
- value.append('}');
- }
-
- /**
- * Read patch edit data defined in value node to NormalizedNode.
- * @param in reader JsonReader reader
- * @return NormalizedNode representing data
- */
- private static NormalizedNode readEditData(final @NonNull JsonReader in,
- final @NonNull Inference targetSchemaNode, final @NonNull InstanceIdentifierContext path) {
- final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
- final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
- final EffectiveModelContext context = path.getSchemaContext();
- JsonParserStream.create(writer, JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02.getShared(context),
- targetSchemaNode)
- .parse(in);
-
- return resultHolder.getResult();
- }
-
- /**
- * Prepare PatchEntity from PatchEdit instance when it satisfies conditions, otherwise throws exception.
- * @param edit Instance of PatchEdit
- * @return PatchEntity Patch entity
- */
- private static PatchEntity prepareEditOperation(final @NonNull PatchEdit edit) {
- if (edit.getOperation() != null && edit.getTargetSchemaNode() != null
- && checkDataPresence(edit.getOperation(), edit.getData() != null)) {
- if (edit.getOperation().isWithValue()) {
- // for lists allow to manipulate with list items through their parent
- final YangInstanceIdentifier targetNode;
- if (edit.getTarget().getLastPathArgument() instanceof NodeIdentifierWithPredicates) {
- targetNode = edit.getTarget().getParent();
- } else {
- targetNode = edit.getTarget();
- }
-
- return new PatchEntity(edit.getId(), edit.getOperation(), targetNode, edit.getData());
- }
-
- return new PatchEntity(edit.getId(), edit.getOperation(), edit.getTarget());
- }
-
- throw new RestconfDocumentedException("Error parsing input", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
- }
-
- /**
- * Check if data is present when operation requires it and not present when operation data is not allowed.
- * @param operation Name of operation
- * @param hasData Data in edit are present/not present
- * @return true if data is present when operation requires it or if there are no data when operation does not
- * allow it, false otherwise
- */
- private static boolean checkDataPresence(final @NonNull PatchEditOperation operation, final boolean hasData) {
- return operation.isWithValue() == hasData;
- }
-
- /**
- * Helper class representing one patch edit.
- */
- private static final class PatchEdit {
- private String id;
- private PatchEditOperation operation;
- private YangInstanceIdentifier target;
- private Inference targetSchemaNode;
- private NormalizedNode data;
-
- public String getId() {
- return id;
- }
-
- public void setId(final String id) {
- this.id = id;
- }
-
- public PatchEditOperation getOperation() {
- return operation;
- }
-
- public void setOperation(final PatchEditOperation operation) {
- this.operation = operation;
- }
-
- public YangInstanceIdentifier getTarget() {
- return target;
- }
-
- public void setTarget(final YangInstanceIdentifier target) {
- this.target = target;
- }
-
- public Inference getTargetSchemaNode() {
- return targetSchemaNode;
- }
-
- public void setTargetSchemaNode(final Inference targetSchemaNode) {
- this.targetSchemaNode = targetSchemaNode;
- }
-
- public NormalizedNode getData() {
- return data;
- }
-
- public void setData(final NormalizedNode data) {
- this.data = data;
- }
-
- public void clear() {
- id = null;
- operation = null;
- target = null;
- targetSchemaNode = null;
- data = null;
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.sal.rest.impl;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.collect.ImmutableMap;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-@Deprecated(forRemoval = true, since = "2.0.6")
-// Non-final for mocking
-public class NormalizedNodeContext {
- private final InstanceIdentifierContext context;
- private final ImmutableMap<String, Object> headers;
- private final WriterParameters writerParameters;
- private final NormalizedNode data;
-
- public NormalizedNodeContext(final InstanceIdentifierContext context,
- final NormalizedNode data, final WriterParameters writerParameters,
- final ImmutableMap<String, Object> headers) {
- this.context = context;
- this.data = data;
- this.writerParameters = writerParameters;
- this.headers = requireNonNull(headers);
- }
-
- public NormalizedNodeContext(final InstanceIdentifierContext context,
- final NormalizedNode data, final WriterParameters writerParameters) {
- this(context, data, writerParameters, ImmutableMap.of());
- }
-
- public NormalizedNodeContext(final InstanceIdentifierContext context,
- final NormalizedNode data) {
- this(context, data, WriterParameters.EMPTY, ImmutableMap.of());
- }
-
- public NormalizedNodeContext(final InstanceIdentifierContext context,
- final NormalizedNode data, final ImmutableMap<String, Object> headers) {
- this(context, data, WriterParameters.EMPTY, headers);
- }
-
- public InstanceIdentifierContext getInstanceIdentifierContext() {
- return context;
- }
-
- public NormalizedNode getData() {
- return data;
- }
-
- public WriterParameters getWriterParameters() {
- return writerParameters;
- }
-
- /**
- * Return headers of {@code NormalizedNodeContext}.
- *
- * @return map of headers
- */
- public ImmutableMap<String, Object> getNewHeaders() {
- return headers;
- }
-}
+++ /dev/null
-/*
- * 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.sal.rest.impl;
-
-import com.google.gson.stream.JsonWriter;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import java.net.URISyntaxException;
-import java.nio.charset.StandardCharsets;
-import java.util.Map.Entry;
-import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.ext.MessageBodyWriter;
-import javax.ws.rs.ext.Provider;
-import javax.xml.stream.XMLStreamException;
-import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.netconf.sal.rest.api.Draft02;
-import org.opendaylight.netconf.sal.rest.api.RestconfNormalizedNodeWriter;
-import org.opendaylight.netconf.sal.rest.api.RestconfService;
-import org.opendaylight.netconf.util.NetconfUtil;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.yangtools.yang.common.XMLNamespace;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DOMSourceAnyxmlNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactory;
-import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier;
-import org.opendaylight.yangtools.yang.data.codec.gson.JSONNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.codec.gson.JsonWriterFactory;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
-import org.xml.sax.SAXException;
-
-/**
- * Normalized node writer for JSON.
- *
- * @deprecated This class will be replaced by NormalizedNodeJsonBodyWriter from restconf-nb-rfc8040
- */
-@Deprecated
-@Provider
-@Produces({
- Draft02.MediaTypes.API + RestconfService.JSON,
- Draft02.MediaTypes.DATA + RestconfService.JSON,
- Draft02.MediaTypes.OPERATION + RestconfService.JSON,
- MediaType.APPLICATION_JSON
-})
-public class NormalizedNodeJsonBodyWriter implements MessageBodyWriter<NormalizedNodeContext> {
-
- private static final int DEFAULT_INDENT_SPACES_NUM = 2;
-
- @Override
- public boolean isWriteable(final Class<?> type, final Type genericType, final Annotation[] annotations,
- final MediaType mediaType) {
- return type.equals(NormalizedNodeContext.class);
- }
-
- @Override
- public long getSize(final NormalizedNodeContext context, final Class<?> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType) {
- return -1;
- }
-
- @Override
- public void writeTo(final NormalizedNodeContext context, final Class<?> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType, final MultivaluedMap<String, Object> httpHeaders,
- final OutputStream entityStream) throws IOException, WebApplicationException {
- if (httpHeaders != null) {
- for (final Entry<String, Object> entry : context.getNewHeaders().entrySet()) {
- httpHeaders.add(entry.getKey(), entry.getValue());
- }
- }
- NormalizedNode data = context.getData();
- if (data == null) {
- return;
- }
-
- final InstanceIdentifierContext identifierCtx = context.getInstanceIdentifierContext();
-
- try (JsonWriter jsonWriter = createJsonWriter(entityStream, context.getWriterParameters().isPrettyPrint())) {
- jsonWriter.beginObject();
- writeNormalizedNode(jsonWriter, identifierCtx, data, context.getWriterParameters().getDepth());
- jsonWriter.endObject();
- jsonWriter.flush();
- }
- }
-
- private static void writeNormalizedNode(final JsonWriter jsonWriter, final InstanceIdentifierContext context,
- // Note: mutable argument
- NormalizedNode data, final @Nullable Integer depth) throws IOException {
-
- final var stack = context.inference().toSchemaInferenceStack();
- final RestconfNormalizedNodeWriter nnWriter;
- if (stack.isEmpty()) {
- /*
- * Creates writer without initialNs and we write children of root data container
- * which is not visible in restconf
- */
- nnWriter = createNormalizedNodeWriter(context, context.inference(), jsonWriter, depth);
- if (data instanceof ContainerNode) {
- writeChildren(nnWriter,(ContainerNode) data);
- } else if (data instanceof DOMSourceAnyxmlNode) {
- try {
- writeChildren(nnWriter,
- (ContainerNode) NetconfUtil.transformDOMSourceToNormalizedNode(
- context.getSchemaContext(), ((DOMSourceAnyxmlNode)data).body()).getResult());
- } catch (XMLStreamException | URISyntaxException | SAXException e) {
- throw new IOException("Cannot write anyxml.", e);
- }
- }
- } else if (context.getSchemaNode() instanceof RpcDefinition) {
- /*
- * RpcDefinition is not supported as initial codec in JSONStreamWriter,
- * so we need to emit initial output declaratation..
- */
- final var rpc = (RpcDefinition) context.getSchemaNode();
- final var tmp = SchemaInferenceStack.of(context.getSchemaContext());
- tmp.enterSchemaTree(rpc.getQName());
- tmp.enterSchemaTree(rpc.getOutput().getQName());
-
- nnWriter = createNormalizedNodeWriter(context, tmp.toInference(), jsonWriter, depth);
- jsonWriter.name("output");
- jsonWriter.beginObject();
- writeChildren(nnWriter, (ContainerNode) data);
- jsonWriter.endObject();
- } else {
- stack.exit();
-
- if (data instanceof MapEntryNode) {
- data = ImmutableNodes.mapNodeBuilder(data.getIdentifier().getNodeType())
- .withChild((MapEntryNode) data)
- .build();
- }
- nnWriter = createNormalizedNodeWriter(context, stack.toInference(), jsonWriter, depth);
- nnWriter.write(data);
- }
- nnWriter.flush();
- }
-
- private static void writeChildren(final RestconfNormalizedNodeWriter nnWriter, final ContainerNode data)
- throws IOException {
- for (final DataContainerChild child : data.body()) {
- nnWriter.write(child);
- }
- }
-
- private static RestconfNormalizedNodeWriter createNormalizedNodeWriter(
- final InstanceIdentifierContext context, final Inference inference, final JsonWriter jsonWriter,
- final @Nullable Integer depth) {
-
- final SchemaNode schema = context.getSchemaNode();
- final JSONCodecFactory codecs = getCodecFactory(context);
-
- final XMLNamespace initialNs;
- if (schema instanceof DataSchemaNode && !((DataSchemaNode)schema).isAugmenting()
- && !(schema instanceof SchemaContext) || schema instanceof RpcDefinition) {
- initialNs = schema.getQName().getNamespace();
- } else {
- initialNs = null;
- }
- final NormalizedNodeStreamWriter streamWriter =
- JSONNormalizedNodeStreamWriter.createNestedWriter(codecs, inference, initialNs, jsonWriter);
- if (depth != null) {
- return DepthAwareNormalizedNodeWriter.forStreamWriter(streamWriter, depth);
- }
-
- return RestconfDelegatingNormalizedNodeWriter.forStreamWriter(streamWriter);
- }
-
- private static JsonWriter createJsonWriter(final OutputStream entityStream, final boolean prettyPrint) {
- if (prettyPrint) {
- return JsonWriterFactory.createJsonWriter(new OutputStreamWriter(entityStream, StandardCharsets.UTF_8),
- DEFAULT_INDENT_SPACES_NUM);
- }
-
- return JsonWriterFactory.createJsonWriter(new OutputStreamWriter(entityStream, StandardCharsets.UTF_8));
- }
-
- private static JSONCodecFactory getCodecFactory(final InstanceIdentifierContext context) {
- // TODO: Performance: Cache JSON Codec factory and schema context
- return JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02.getShared(context.getSchemaContext());
- }
-}
+++ /dev/null
-/*
- * 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.sal.rest.impl;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import java.net.URISyntaxException;
-import java.nio.charset.StandardCharsets;
-import java.util.Map.Entry;
-import javanet.staxutils.IndentingXMLStreamWriter;
-import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.ext.MessageBodyWriter;
-import javax.ws.rs.ext.Provider;
-import javax.xml.XMLConstants;
-import javax.xml.stream.FactoryConfigurationError;
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.netconf.sal.rest.api.Draft02;
-import org.opendaylight.netconf.sal.rest.api.RestconfNormalizedNodeWriter;
-import org.opendaylight.netconf.sal.rest.api.RestconfService;
-import org.opendaylight.netconf.util.NetconfUtil;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DOMSourceAnyxmlNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
-import org.xml.sax.SAXException;
-
-/**
- * Normalized node writer for XML.
- *
- * @deprecated This class will be replaced by NormalizedNodeXmlBodyWriter from restconf-nb-rfc8040
- */
-@Deprecated
-@Provider
-@Produces({
- Draft02.MediaTypes.API + RestconfService.XML,
- Draft02.MediaTypes.DATA + RestconfService.XML,
- Draft02.MediaTypes.OPERATION + RestconfService.XML,
- MediaType.APPLICATION_XML,
- MediaType.TEXT_XML
-})
-public class NormalizedNodeXmlBodyWriter implements MessageBodyWriter<NormalizedNodeContext> {
-
- private static final XMLOutputFactory XML_FACTORY;
-
- static {
- XML_FACTORY = XMLOutputFactory.newFactory();
- XML_FACTORY.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
- }
-
- @Override
- public boolean isWriteable(final Class<?> type, final Type genericType, final Annotation[] annotations,
- final MediaType mediaType) {
- return type.equals(NormalizedNodeContext.class);
- }
-
- @Override
- public long getSize(final NormalizedNodeContext context, final Class<?> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType) {
- return -1;
- }
-
- @Override
- public void writeTo(final NormalizedNodeContext context, final Class<?> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType,
- final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream) throws IOException,
- WebApplicationException {
- for (final Entry<String, Object> entry : context.getNewHeaders().entrySet()) {
- httpHeaders.add(entry.getKey(), entry.getValue());
- }
- final InstanceIdentifierContext pathContext = context.getInstanceIdentifierContext();
- if (context.getData() == null) {
- return;
- }
-
- XMLStreamWriter xmlWriter;
- try {
- xmlWriter = XML_FACTORY.createXMLStreamWriter(entityStream, StandardCharsets.UTF_8.name());
- if (context.getWriterParameters().isPrettyPrint()) {
- xmlWriter = new IndentingXMLStreamWriter(xmlWriter);
- }
- } catch (final XMLStreamException | FactoryConfigurationError e) {
- throw new IllegalStateException(e);
- }
- final NormalizedNode data = context.getData();
-
- writeNormalizedNode(xmlWriter, pathContext.inference().toSchemaInferenceStack(), pathContext, data,
- context.getWriterParameters().getDepth());
- }
-
- private static void writeNormalizedNode(final XMLStreamWriter xmlWriter, final SchemaInferenceStack stack,
- final InstanceIdentifierContext pathContext, NormalizedNode data, final @Nullable Integer depth)
- throws IOException {
- final RestconfNormalizedNodeWriter nnWriter;
- final EffectiveModelContext schemaCtx = pathContext.getSchemaContext();
- if (stack.isEmpty()) {
- nnWriter = createNormalizedNodeWriter(xmlWriter, pathContext.inference(), depth);
- if (data instanceof DOMSourceAnyxmlNode) {
- try {
- writeElements(xmlWriter, nnWriter,
- (ContainerNode) NetconfUtil.transformDOMSourceToNormalizedNode(schemaCtx,
- ((DOMSourceAnyxmlNode)data).body()).getResult());
- } catch (XMLStreamException | URISyntaxException | SAXException e) {
- throw new IOException("Cannot write anyxml", e);
- }
- } else {
- writeElements(xmlWriter, nnWriter, (ContainerNode) data);
- }
- } else if (pathContext.getSchemaNode() instanceof RpcDefinition) {
- final var rpc = (RpcDefinition) pathContext.getSchemaNode();
- final var tmp = SchemaInferenceStack.of(pathContext.getSchemaContext());
- tmp.enterSchemaTree(rpc.getQName());
- tmp.enterSchemaTree(rpc.getOutput().getQName());
-
- nnWriter = createNormalizedNodeWriter(xmlWriter, tmp.toInference(), depth);
- writeElements(xmlWriter, nnWriter, (ContainerNode) data);
- } else {
- stack.exit();
- nnWriter = createNormalizedNodeWriter(xmlWriter, stack.toInference(), depth);
- if (data instanceof MapEntryNode) {
- // Restconf allows returning one list item. We need to wrap it
- // in map node in order to serialize it properly
- data = ImmutableNodes.mapNodeBuilder(data.getIdentifier().getNodeType())
- .addChild((MapEntryNode) data)
- .build();
- }
- nnWriter.write(data);
- }
- nnWriter.flush();
- }
-
- private static RestconfNormalizedNodeWriter createNormalizedNodeWriter(final XMLStreamWriter xmlWriter,
- final Inference inference, final @Nullable Integer depth) {
- final NormalizedNodeStreamWriter xmlStreamWriter =
- XMLStreamNormalizedNodeStreamWriter.create(xmlWriter, inference);
- if (depth != null) {
- return DepthAwareNormalizedNodeWriter.forStreamWriter(xmlStreamWriter, depth);
- }
-
- return RestconfDelegatingNormalizedNodeWriter.forStreamWriter(xmlStreamWriter);
- }
-
- private static void writeElements(final XMLStreamWriter xmlWriter, final RestconfNormalizedNodeWriter nnWriter,
- final ContainerNode data) throws IOException {
- final QName name = data.getIdentifier().getNodeType();
- try {
- xmlWriter.writeStartElement(XMLConstants.DEFAULT_NS_PREFIX, name.getLocalName(),
- name.getNamespace().toString());
- xmlWriter.writeDefaultNamespace(name.getNamespace().toString());
- for (final NormalizedNode child : data.body()) {
- nnWriter.write(child);
- }
- nnWriter.flush();
- xmlWriter.writeEndElement();
- xmlWriter.flush();
- } catch (final XMLStreamException e) {
- throw new IOException("Failed to write elements", e);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.sal.rest.impl;
-
-import com.google.gson.stream.JsonWriter;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.ext.MessageBodyWriter;
-import javax.ws.rs.ext.Provider;
-import org.opendaylight.netconf.sal.rest.api.Draft02;
-import org.opendaylight.netconf.sal.rest.api.RestconfService;
-import org.opendaylight.restconf.common.errors.RestconfError;
-import org.opendaylight.restconf.common.patch.PatchStatusContext;
-import org.opendaylight.restconf.common.patch.PatchStatusEntity;
-import org.opendaylight.yangtools.yang.data.codec.gson.JsonWriterFactory;
-
-
-@Provider
-@Produces({ Draft02.MediaTypes.PATCH_STATUS + RestconfService.JSON })
-public class PatchJsonBodyWriter implements MessageBodyWriter<PatchStatusContext> {
-
- @Override
- public boolean isWriteable(final Class<?> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType) {
- return type.equals(PatchStatusContext.class);
- }
-
- @Override
- public long getSize(final PatchStatusContext patchStatusContext, final Class<?> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType) {
- return -1;
- }
-
- @Override
- public void writeTo(final PatchStatusContext patchStatusContext, final Class<?> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType,
- final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream)
- throws IOException, WebApplicationException {
-
- final JsonWriter jsonWriter = createJsonWriter(entityStream);
- jsonWriter.beginObject().name("ietf-yang-patch:yang-patch-status");
- jsonWriter.beginObject();
- jsonWriter.name("patch-id").value(patchStatusContext.getPatchId());
- if (patchStatusContext.isOk()) {
- reportSuccess(jsonWriter);
- } else {
- if (patchStatusContext.getGlobalErrors() != null) {
- reportErrors(patchStatusContext.getGlobalErrors(), jsonWriter);
- }
-
- jsonWriter.name("edit-status");
- jsonWriter.beginObject();
- jsonWriter.name("edit");
- jsonWriter.beginArray();
- for (final PatchStatusEntity patchStatusEntity : patchStatusContext.getEditCollection()) {
- jsonWriter.beginObject();
- jsonWriter.name("edit-id").value(patchStatusEntity.getEditId());
- if (patchStatusEntity.getEditErrors() != null) {
- reportErrors(patchStatusEntity.getEditErrors(), jsonWriter);
- } else {
- if (patchStatusEntity.isOk()) {
- reportSuccess(jsonWriter);
- }
- }
- jsonWriter.endObject();
- }
- jsonWriter.endArray();
- jsonWriter.endObject();
- }
- jsonWriter.endObject();
- jsonWriter.endObject();
- jsonWriter.flush();
- }
-
- private static void reportSuccess(final JsonWriter jsonWriter) throws IOException {
- jsonWriter.name("ok").beginArray().nullValue().endArray();
- }
-
- private static void reportErrors(final List<RestconfError> errors, final JsonWriter jsonWriter) throws IOException {
- jsonWriter.name("errors");
- jsonWriter.beginObject();
- jsonWriter.name("error");
- jsonWriter.beginArray();
-
- for (final RestconfError restconfError : errors) {
- jsonWriter.beginObject();
- jsonWriter.name("error-type").value(restconfError.getErrorType().elementBody());
- jsonWriter.name("error-tag").value(restconfError.getErrorTag().elementBody());
-
- // optional node
- if (restconfError.getErrorPath() != null) {
- jsonWriter.name("error-path").value(restconfError.getErrorPath().toString());
- }
-
- // optional node
- if (restconfError.getErrorMessage() != null) {
- jsonWriter.name("error-message").value(restconfError.getErrorMessage());
- }
-
- // optional node
- if (restconfError.getErrorInfo() != null) {
- jsonWriter.name("error-info").value(restconfError.getErrorInfo());
- }
-
- jsonWriter.endObject();
- }
-
- jsonWriter.endArray();
- jsonWriter.endObject();
- }
-
- private static JsonWriter createJsonWriter(final OutputStream entityStream) {
- return JsonWriterFactory.createJsonWriter(new OutputStreamWriter(entityStream, StandardCharsets.UTF_8));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.sal.rest.impl;
-
-import java.io.OutputStream;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.ext.MessageBodyWriter;
-import javax.ws.rs.ext.Provider;
-import javax.xml.stream.FactoryConfigurationError;
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-import org.opendaylight.netconf.sal.rest.api.Draft02;
-import org.opendaylight.netconf.sal.rest.api.RestconfService;
-import org.opendaylight.restconf.common.errors.RestconfError;
-import org.opendaylight.restconf.common.patch.PatchStatusContext;
-import org.opendaylight.restconf.common.patch.PatchStatusEntity;
-
-@Provider
-@Produces({ Draft02.MediaTypes.PATCH_STATUS + RestconfService.XML })
-public class PatchXmlBodyWriter implements MessageBodyWriter<PatchStatusContext> {
-
- private static final XMLOutputFactory XML_FACTORY;
-
- static {
- XML_FACTORY = XMLOutputFactory.newFactory();
- XML_FACTORY.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
- }
-
- @Override
- public boolean isWriteable(final Class<?> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType) {
- return type.equals(PatchStatusContext.class);
- }
-
- @Override
- public long getSize(final PatchStatusContext patchStatusContext, final Class<?> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType) {
- return -1;
- }
-
- @Override
- public void writeTo(final PatchStatusContext patchStatusContext, final Class<?> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType,
- final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream)
- throws WebApplicationException {
-
- try {
- final XMLStreamWriter xmlWriter =
- XML_FACTORY.createXMLStreamWriter(entityStream, StandardCharsets.UTF_8.name());
- writeDocument(xmlWriter, patchStatusContext);
- } catch (final XMLStreamException | FactoryConfigurationError e) {
- throw new IllegalStateException(e);
- }
- }
-
- private static void writeDocument(final XMLStreamWriter writer, final PatchStatusContext context)
- throws XMLStreamException {
- writer.writeStartElement("", "yang-patch-status", "urn:ietf:params:xml:ns:yang:ietf-yang-patch");
- writer.writeStartElement("patch-id");
- writer.writeCharacters(context.getPatchId());
- writer.writeEndElement();
-
- if (context.isOk()) {
- writer.writeEmptyElement("ok");
- } else {
- if (context.getGlobalErrors() != null) {
- reportErrors(context.getGlobalErrors(), writer);
- }
- writer.writeStartElement("edit-status");
- for (final PatchStatusEntity patchStatusEntity : context.getEditCollection()) {
- writer.writeStartElement("edit");
- writer.writeStartElement("edit-id");
- writer.writeCharacters(patchStatusEntity.getEditId());
- writer.writeEndElement();
- if (patchStatusEntity.getEditErrors() != null) {
- reportErrors(patchStatusEntity.getEditErrors(), writer);
- } else {
- if (patchStatusEntity.isOk()) {
- writer.writeEmptyElement("ok");
- }
- }
- writer.writeEndElement();
- }
- writer.writeEndElement();
-
- }
- writer.writeEndElement();
-
- writer.flush();
- }
-
- private static void reportErrors(final List<RestconfError> errors, final XMLStreamWriter writer)
- throws XMLStreamException {
- writer.writeStartElement("errors");
-
- for (final RestconfError restconfError : errors) {
- writer.writeStartElement("error-type");
- writer.writeCharacters(restconfError.getErrorType().elementBody());
- writer.writeEndElement();
-
- writer.writeStartElement("error-tag");
- writer.writeCharacters(restconfError.getErrorTag().elementBody());
- writer.writeEndElement();
-
- // optional node
- if (restconfError.getErrorPath() != null) {
- writer.writeStartElement("error-path");
- writer.writeCharacters(restconfError.getErrorPath().toString());
- writer.writeEndElement();
- }
-
- // optional node
- if (restconfError.getErrorMessage() != null) {
- writer.writeStartElement("error-message");
- writer.writeCharacters(restconfError.getErrorMessage());
- writer.writeEndElement();
- }
-
- // optional node
- if (restconfError.getErrorInfo() != null) {
- writer.writeStartElement("error-info");
- writer.writeCharacters(restconfError.getErrorInfo());
- writer.writeEndElement();
- }
- }
-
- writer.writeEndElement();
- }
-}
+++ /dev/null
-/*
- * 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.sal.rest.impl;
-
-import com.google.common.collect.ImmutableSet;
-import java.util.HashSet;
-import java.util.Set;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.ws.rs.core.Application;
-import org.opendaylight.netconf.md.sal.rest.schema.SchemaExportContentYangBodyWriter;
-import org.opendaylight.netconf.md.sal.rest.schema.SchemaExportContentYinBodyWriter;
-import org.opendaylight.netconf.md.sal.rest.schema.SchemaRetrievalServiceImpl;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.netconf.sal.restconf.impl.StatisticsRestconfServiceWrapper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Singleton
-@Deprecated(since = "2.0.12")
-public class RestconfApplication extends Application {
- private static final Logger LOG = LoggerFactory.getLogger(RestconfApplication.class);
-
- private final ControllerContext controllerContext;
- private final StatisticsRestconfServiceWrapper statsServiceWrapper;
-
- @Inject
- public RestconfApplication(final ControllerContext controllerContext,
- final StatisticsRestconfServiceWrapper statsServiceWrapper) {
- this.controllerContext = controllerContext;
- this.statsServiceWrapper = statsServiceWrapper;
- LOG.warn("Pre-standard version of RESTCONF activated. Please note that this implementation is considered "
- + "obsoleve and WILL BE REMOVED IN THE NEXT MAJOR RELEASE. Please use the RFC8040-compliant "
- + "implementation instead.");
- }
-
- @Override
- public Set<Class<?>> getClasses() {
- return ImmutableSet.<Class<?>>builder()
- .add(PatchJsonBodyWriter.class)
- .add(PatchXmlBodyWriter.class)
- .add(NormalizedNodeJsonBodyWriter.class)
- .add(NormalizedNodeXmlBodyWriter.class)
- .add(SchemaExportContentYinBodyWriter.class)
- .add(SchemaExportContentYangBodyWriter.class)
- .build();
- }
-
- @Override
- public Set<Object> getSingletons() {
- final Set<Object> singletons = new HashSet<>();
- final SchemaRetrievalServiceImpl schemaRetrieval = new SchemaRetrievalServiceImpl(controllerContext);
- singletons.add(schemaRetrieval);
- singletons.add(new RestconfCompositeWrapper(statsServiceWrapper, schemaRetrieval));
- singletons.add(new RestconfDocumentedExceptionMapper(controllerContext));
- singletons.add(new XmlNormalizedNodeBodyReader(controllerContext));
- singletons.add(new JsonNormalizedNodeBodyReader(controllerContext));
- singletons.add(new XmlToPatchBodyReader(controllerContext));
- singletons.add(new JsonToPatchBodyReader(controllerContext));
-// singletons.add(StructuredDataToXmlProvider.INSTANCE);
-// singletons.add(StructuredDataToJsonProvider.INSTANCE);
-// singletons.add(JsonToCompositeNodeProvider.INSTANCE);
-// singletons.add(XmlToCompositeNodeProvider.INSTANCE);
- return singletons;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.sal.rest.impl;
-
-import static java.util.Objects.requireNonNull;
-
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-import org.opendaylight.netconf.md.sal.rest.schema.SchemaRetrievalService;
-import org.opendaylight.netconf.sal.rest.api.RestconfService;
-import org.opendaylight.restconf.common.patch.PatchContext;
-import org.opendaylight.restconf.common.patch.PatchStatusContext;
-import org.opendaylight.restconf.common.schema.SchemaExportContext;
-
-public class RestconfCompositeWrapper implements RestconfService, SchemaRetrievalService {
-
- private final RestconfService restconf;
- private final SchemaRetrievalService schema;
-
- public RestconfCompositeWrapper(final RestconfService restconf, final SchemaRetrievalService schema) {
- this.restconf = requireNonNull(restconf);
- this.schema = requireNonNull(schema);
- }
-
- @Override
- public Object getRoot() {
- return this.restconf.getRoot();
- }
-
- @Override
- public NormalizedNodeContext getModules(final UriInfo uriInfo) {
- return this.restconf.getModules(uriInfo);
- }
-
- @Override
- public NormalizedNodeContext getModules(final String identifier, final UriInfo uriInfo) {
- return this.restconf.getModules(identifier, uriInfo);
- }
-
- @Override
- public NormalizedNodeContext getModule(final String identifier, final UriInfo uriInfo) {
- return this.restconf.getModule(identifier, uriInfo);
- }
-
- @Override
- public String getOperationsJSON() {
- return this.restconf.getOperationsJSON();
- }
-
- @Override
- public String getOperationsXML() {
- return this.restconf.getOperationsXML();
- }
-
- @Override
- public NormalizedNodeContext getOperations(final String identifier, final UriInfo uriInfo) {
- return this.restconf.getOperations(identifier, uriInfo);
- }
-
- @Override
- public NormalizedNodeContext invokeRpc(final String identifier, final NormalizedNodeContext payload,
- final UriInfo uriInfo) {
- return this.restconf.invokeRpc(identifier, payload, uriInfo);
- }
-
- @Override
- public NormalizedNodeContext readConfigurationData(final String identifier, final UriInfo uriInfo) {
- return this.restconf.readConfigurationData(identifier, uriInfo);
- }
-
- @Override
- public NormalizedNodeContext readOperationalData(final String identifier, final UriInfo uriInfo) {
- return this.restconf.readOperationalData(identifier, uriInfo);
- }
-
- @Override
- public Response updateConfigurationData(final String identifier, final NormalizedNodeContext payload,
- final UriInfo uriInfo) {
- return this.restconf.updateConfigurationData(identifier, payload, uriInfo);
- }
-
- @Override
- public Response createConfigurationData(final String identifier, final NormalizedNodeContext payload,
- final UriInfo uriInfo) {
- return this.restconf.createConfigurationData(identifier, payload, uriInfo);
- }
-
- @Override
- public Response createConfigurationData(final NormalizedNodeContext payload, final UriInfo uriInfo) {
- return this.restconf.createConfigurationData(payload, uriInfo);
- }
-
- @Override
- public Response deleteConfigurationData(final String identifier) {
- return this.restconf.deleteConfigurationData(identifier);
- }
-
- @Override
- public NormalizedNodeContext subscribeToStream(final String identifier, final UriInfo uriInfo) {
- return this.restconf.subscribeToStream(identifier, uriInfo);
- }
-
- @Override
- public NormalizedNodeContext getAvailableStreams(final UriInfo uriInfo) {
- return this.restconf.getAvailableStreams(uriInfo);
- }
-
- @Override
- public PatchStatusContext patchConfigurationData(final String identifier, final PatchContext payload,
- final UriInfo uriInfo) {
- return this.restconf.patchConfigurationData(identifier, payload, uriInfo);
- }
-
- @Override
- public PatchStatusContext patchConfigurationData(final PatchContext context, final UriInfo uriInfo) {
- return this.restconf.patchConfigurationData(context, uriInfo);
- }
-
- @Override
- public SchemaExportContext getSchema(final String mountId) {
- return this.schema.getSchema(mountId);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.sal.rest.impl;
-
-import java.io.IOException;
-import org.opendaylight.netconf.sal.rest.api.RestconfNormalizedNodeWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
-
-/**
- * This class just delegates all of the functionality to Yangtools normalized node writer.
- */
-public final class RestconfDelegatingNormalizedNodeWriter implements RestconfNormalizedNodeWriter {
- private final NormalizedNodeWriter delegNNWriter;
-
- private RestconfDelegatingNormalizedNodeWriter(final NormalizedNodeStreamWriter streamWriter, final boolean
- orderKeyLeaves) {
- this.delegNNWriter = NormalizedNodeWriter.forStreamWriter(streamWriter, orderKeyLeaves);
- }
-
- public static RestconfDelegatingNormalizedNodeWriter forStreamWriter(final NormalizedNodeStreamWriter writer) {
- return forStreamWriter(writer, true);
- }
-
- public static RestconfDelegatingNormalizedNodeWriter forStreamWriter(final NormalizedNodeStreamWriter writer,
- final boolean orderKeyLeaves) {
- return new RestconfDelegatingNormalizedNodeWriter(writer, orderKeyLeaves);
- }
-
- @Override
- public RestconfDelegatingNormalizedNodeWriter write(final NormalizedNode node) throws IOException {
- delegNNWriter.write(node);
- return this;
- }
-
- @Override
- public void flush() throws IOException {
- delegNNWriter.flush();
- }
-
- @Override
- public void close() throws IOException {
- delegNNWriter.close();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Brocade Communications 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.sal.rest.impl;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
-
-import com.google.gson.stream.JsonWriter;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.List;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
-import javax.ws.rs.ext.ExceptionMapper;
-import javax.ws.rs.ext.Provider;
-import javax.xml.XMLConstants;
-import javax.xml.stream.FactoryConfigurationError;
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-import org.opendaylight.netconf.sal.rest.api.Draft02;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.restconf.common.ErrorTags;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.errors.RestconfError;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.XMLNamespace;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.SystemMapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.CollectionNodeBuilder;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.ForwardingNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
-import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier;
-import org.opendaylight.yangtools.yang.data.codec.gson.JSONNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.codec.gson.JsonWriterFactory;
-import org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.data.impl.schema.SchemaAwareBuilders;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This class defines an ExceptionMapper that handles RestconfDocumentedExceptions thrown by resource implementations
- * and translates appropriately to restconf error response as defined in the RESTCONF RFC draft.
- *
- * @author Thomas Pantelis
- */
-@Provider
-public class RestconfDocumentedExceptionMapper implements ExceptionMapper<RestconfDocumentedException> {
-
- private static final Logger LOG = LoggerFactory.getLogger(RestconfDocumentedExceptionMapper.class);
-
- private static final XMLOutputFactory XML_FACTORY;
-
- static {
- XML_FACTORY = XMLOutputFactory.newFactory();
- XML_FACTORY.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
- }
-
- @Context
- private HttpHeaders headers;
-
- private final ControllerContext controllerContext;
-
- public RestconfDocumentedExceptionMapper(final ControllerContext controllerContext) {
- this.controllerContext = requireNonNull(controllerContext);
- }
-
- @Override
- public Response toResponse(final RestconfDocumentedException exception) {
-
- LOG.debug("In toResponse: {}", exception.getMessage());
-
- final List<MediaType> mediaTypeList = new ArrayList<>();
- if (headers.getMediaType() != null) {
- mediaTypeList.add(headers.getMediaType());
- }
-
- mediaTypeList.addAll(headers.getAcceptableMediaTypes());
- final MediaType mediaType = mediaTypeList.stream().filter(type -> !type.equals(MediaType.WILDCARD_TYPE))
- .findFirst().orElse(MediaType.APPLICATION_JSON_TYPE);
-
- LOG.debug("Using MediaType: {}", mediaType);
-
- final List<RestconfError> errors = exception.getErrors();
- if (errors.isEmpty()) {
- // We don't actually want to send any content but, if we don't set any content here,
- // the tomcat front-end will send back an html error report. To prevent that, set a
- // single space char in the entity.
-
- return Response.status(exception.getStatus()).type(MediaType.TEXT_PLAIN_TYPE).entity(" ").build();
- }
-
- final Status status = ErrorTags.statusOf(errors.iterator().next().getErrorTag());
- final var errorsEntry = controllerContext.getRestconfModuleErrorsSchemaNode();
- if (errorsEntry == null) {
- return Response.status(status).type(MediaType.TEXT_PLAIN_TYPE).entity(exception.getMessage()).build();
- }
-
- final var errorsSchemaNode = errorsEntry.getValue();
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> errContBuild =
- SchemaAwareBuilders.containerBuilder(errorsSchemaNode);
-
- final var schemaList = ControllerContext.findInstanceDataChildrenByName(errorsSchemaNode,
- Draft02.RestConfModule.ERROR_LIST_SCHEMA_NODE);
- final DataSchemaNode errListSchemaNode = ControllerContext.getFirst(schemaList);
- checkState(errListSchemaNode instanceof ListSchemaNode, "Found Error SchemaNode isn't ListSchemaNode");
- final CollectionNodeBuilder<MapEntryNode, SystemMapNode> listErorsBuilder = SchemaAwareBuilders
- .mapBuilder((ListSchemaNode) errListSchemaNode);
-
-
- for (final RestconfError error : errors) {
- listErorsBuilder.withChild(toErrorEntryNode(error, errListSchemaNode));
- }
- errContBuild.withChild(listErorsBuilder.build());
-
- final NormalizedNodeContext errContext = new NormalizedNodeContext(
- InstanceIdentifierContext.ofStack(errorsEntry.getKey(), null), errContBuild.build());
-
- final String responseBody;
- if (mediaType.getSubtype().endsWith("json")) {
- responseBody = toJsonResponseBody(errContext);
- } else {
- responseBody = toXMLResponseBody(errContext);
- }
-
- return Response.status(status).type(mediaType).entity(responseBody).build();
- }
-
- private static MapEntryNode toErrorEntryNode(final RestconfError error, final DataSchemaNode errListSchemaNode) {
- checkArgument(errListSchemaNode instanceof ListSchemaNode,
- "errListSchemaNode has to be of type ListSchemaNode");
- final ListSchemaNode listStreamSchemaNode = (ListSchemaNode) errListSchemaNode;
- final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> errNodeValues = SchemaAwareBuilders
- .mapEntryBuilder(listStreamSchemaNode);
-
- var lsChildDataSchemaNode = ControllerContext.findInstanceDataChildrenByName(
- listStreamSchemaNode, "error-type");
- final DataSchemaNode errTypSchemaNode = ControllerContext.getFirst(lsChildDataSchemaNode);
- checkState(errTypSchemaNode instanceof LeafSchemaNode);
- errNodeValues.withChild(SchemaAwareBuilders.leafBuilder((LeafSchemaNode) errTypSchemaNode)
- .withValue(error.getErrorType().elementBody()).build());
-
- lsChildDataSchemaNode = ControllerContext.findInstanceDataChildrenByName(
- listStreamSchemaNode, "error-tag");
- final DataSchemaNode errTagSchemaNode = ControllerContext.getFirst(lsChildDataSchemaNode);
- checkState(errTagSchemaNode instanceof LeafSchemaNode);
- errNodeValues.withChild(SchemaAwareBuilders.leafBuilder((LeafSchemaNode) errTagSchemaNode)
- .withValue(error.getErrorTag().elementBody()).build());
-
- if (error.getErrorAppTag() != null) {
- lsChildDataSchemaNode = ControllerContext.findInstanceDataChildrenByName(
- listStreamSchemaNode, "error-app-tag");
- final DataSchemaNode errAppTagSchemaNode = ControllerContext.getFirst(lsChildDataSchemaNode);
- checkState(errAppTagSchemaNode instanceof LeafSchemaNode);
- errNodeValues.withChild(SchemaAwareBuilders.leafBuilder((LeafSchemaNode) errAppTagSchemaNode)
- .withValue(error.getErrorAppTag()).build());
- }
-
- lsChildDataSchemaNode = ControllerContext.findInstanceDataChildrenByName(
- listStreamSchemaNode, "error-message");
- final DataSchemaNode errMsgSchemaNode = ControllerContext.getFirst(lsChildDataSchemaNode);
- checkState(errMsgSchemaNode instanceof LeafSchemaNode);
- errNodeValues.withChild(SchemaAwareBuilders.leafBuilder((LeafSchemaNode) errMsgSchemaNode)
- .withValue(error.getErrorMessage()).build());
-
- if (error.getErrorInfo() != null) {
- // Oddly, error-info is defined as an empty container in the restconf yang. Apparently the
- // intention is for implementors to define their own data content so we'll just treat it as a leaf
- // with string data.
- errNodeValues.withChild(ImmutableNodes.leafNode(Draft02.RestConfModule.ERROR_INFO_QNAME,
- error.getErrorInfo()));
- }
-
- // TODO : find how could we add possible "error-path"
-
- return errNodeValues.build();
- }
-
- private static String toJsonResponseBody(final NormalizedNodeContext errorsNode) {
- final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
- NormalizedNode data = errorsNode.getData();
- final InstanceIdentifierContext context = errorsNode.getInstanceIdentifierContext();
- final DataSchemaNode schema = (DataSchemaNode) context.getSchemaNode();
-
- final OutputStreamWriter outputWriter = new OutputStreamWriter(outStream, StandardCharsets.UTF_8);
- if (data == null) {
- throw new RestconfDocumentedException(Response.Status.NOT_FOUND);
- }
-
- final boolean isDataRoot;
- final var stack = context.inference().toSchemaInferenceStack();
- if (stack.isEmpty()) {
- isDataRoot = true;
- } else {
- isDataRoot = false;
- stack.exit();
- // FIXME: Add proper handling of reading root.
- }
-
- XMLNamespace initialNs = null;
- if (!schema.isAugmenting() && !(schema instanceof SchemaContext)) {
- initialNs = schema.getQName().getNamespace();
- }
-
- final JsonWriter jsonWriter = JsonWriterFactory.createJsonWriter(outputWriter);
- final NormalizedNodeStreamWriter jsonStreamWriter = JSONNormalizedNodeStreamWriter.createExclusiveWriter(
- JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02.getShared(context.getSchemaContext()),
- stack.toInference(), initialNs, jsonWriter);
-
- // We create a delegating writer to special-case error-info as error-info is defined as an empty
- // container in the restconf yang schema but we create a leaf node so we can output it. The delegate
- // stream writer validates the node type against the schema and thus will expect a LeafSchemaNode but
- // the schema has a ContainerSchemaNode so, to avoid an error, we override the leafNode behavior
- // for error-info.
- final NormalizedNodeStreamWriter streamWriter = new ForwardingNormalizedNodeStreamWriter() {
- private boolean inOurLeaf;
-
- @Override
- protected NormalizedNodeStreamWriter delegate() {
- return jsonStreamWriter;
- }
-
- @Override
- public void startLeafNode(final NodeIdentifier name) throws IOException {
- if (name.getNodeType().equals(Draft02.RestConfModule.ERROR_INFO_QNAME)) {
- inOurLeaf = true;
- jsonWriter.name(Draft02.RestConfModule.ERROR_INFO_QNAME.getLocalName());
- } else {
- super.startLeafNode(name);
- }
- }
-
- @Override
- public void scalarValue(final Object value) throws IOException {
- if (inOurLeaf) {
- jsonWriter.value(value.toString());
- } else {
- super.scalarValue(value);
- }
- }
-
- @Override
- public void endNode() throws IOException {
- if (inOurLeaf) {
- inOurLeaf = false;
- } else {
- super.endNode();
- }
- }
- };
-
- final NormalizedNodeWriter nnWriter = NormalizedNodeWriter.forStreamWriter(streamWriter);
- try {
- if (isDataRoot) {
- writeDataRoot(outputWriter,nnWriter,(ContainerNode) data);
- } else {
- if (data instanceof MapEntryNode) {
- data = ImmutableNodes.mapNodeBuilder(data.getIdentifier().getNodeType())
- .withChild((MapEntryNode) data)
- .build();
- }
- nnWriter.write(data);
- }
- nnWriter.flush();
- outputWriter.flush();
- } catch (final IOException e) {
- LOG.warn("Error writing error response body", e);
- }
-
- try {
- streamWriter.close();
- } catch (IOException e) {
- LOG.warn("Failed to close stream writer", e);
- }
-
- return outStream.toString(StandardCharsets.UTF_8);
- }
-
- private static String toXMLResponseBody(final NormalizedNodeContext errorsNode) {
- final InstanceIdentifierContext pathContext = errorsNode.getInstanceIdentifierContext();
- final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
-
- final XMLStreamWriter xmlWriter;
- try {
- xmlWriter = XML_FACTORY.createXMLStreamWriter(outStream, StandardCharsets.UTF_8.name());
- } catch (final XMLStreamException | FactoryConfigurationError e) {
- throw new IllegalStateException(e);
- }
- NormalizedNode data = errorsNode.getData();
-
- final boolean isDataRoot;
- final var stack = pathContext.inference().toSchemaInferenceStack();
- if (stack.isEmpty()) {
- isDataRoot = true;
- } else {
- isDataRoot = false;
- stack.exit();
- }
-
- final NormalizedNodeStreamWriter xmlStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(xmlWriter,
- stack.toInference());
-
- // We create a delegating writer to special-case error-info as error-info is defined as an empty
- // container in the restconf yang schema but we create a leaf node so we can output it. The delegate
- // stream writer validates the node type against the schema and thus will expect a LeafSchemaNode but
- // the schema has a ContainerSchemaNode so, to avoid an error, we override the leafNode behavior
- // for error-info.
- final NormalizedNodeStreamWriter streamWriter = new ForwardingNormalizedNodeStreamWriter() {
- private boolean inOurLeaf;
-
- @Override
- protected NormalizedNodeStreamWriter delegate() {
- return xmlStreamWriter;
- }
-
- @Override
- public void startLeafNode(final NodeIdentifier name) throws IOException {
- if (name.getNodeType().equals(Draft02.RestConfModule.ERROR_INFO_QNAME)) {
- String ns = Draft02.RestConfModule.ERROR_INFO_QNAME.getNamespace().toString();
- try {
- xmlWriter.writeStartElement(XMLConstants.DEFAULT_NS_PREFIX,
- Draft02.RestConfModule.ERROR_INFO_QNAME.getLocalName(), ns);
- } catch (XMLStreamException e) {
- throw new IOException("Error writing error-info", e);
- }
- inOurLeaf = true;
- } else {
- super.startLeafNode(name);
- }
- }
-
- @Override
- public void scalarValue(final Object value) throws IOException {
- if (inOurLeaf) {
- try {
- xmlWriter.writeCharacters(value.toString());
- } catch (XMLStreamException e) {
- throw new IOException("Error writing error-info", e);
- }
- } else {
- super.scalarValue(value);
- }
- }
-
- @Override
- public void endNode() throws IOException {
- if (inOurLeaf) {
- try {
- xmlWriter.writeEndElement();
- } catch (XMLStreamException e) {
- throw new IOException("Error writing error-info", e);
- }
- inOurLeaf = false;
- } else {
- super.endNode();
- }
- }
- };
-
- final NormalizedNodeWriter nnWriter = NormalizedNodeWriter.forStreamWriter(streamWriter);
- try {
- if (isDataRoot) {
- writeRootElement(xmlWriter, nnWriter, (ContainerNode) data);
- } else {
- if (data instanceof MapEntryNode) {
- // Restconf allows returning one list item. We need to wrap it
- // in map node in order to serialize it properly
- data = ImmutableNodes.mapNodeBuilder(data.getIdentifier().getNodeType())
- .addChild((MapEntryNode) data)
- .build();
- }
- nnWriter.write(data);
- nnWriter.flush();
- }
- } catch (final IOException e) {
- LOG.warn("Error writing error response body.", e);
- }
-
- return outStream.toString(StandardCharsets.UTF_8);
- }
-
- private static void writeRootElement(final XMLStreamWriter xmlWriter, final NormalizedNodeWriter nnWriter,
- final ContainerNode data) throws IOException {
- final QName name = SchemaContext.NAME;
- try {
- xmlWriter.writeStartElement(name.getNamespace().toString(), name.getLocalName());
- for (final DataContainerChild child : data.body()) {
- nnWriter.write(child);
- }
- nnWriter.flush();
- xmlWriter.writeEndElement();
- xmlWriter.flush();
- } catch (final XMLStreamException e) {
- throw new IOException("Failed to write elements", e);
- }
- }
-
- private static void writeDataRoot(final OutputStreamWriter outputWriter, final NormalizedNodeWriter nnWriter,
- final ContainerNode data) throws IOException {
- for (final DataContainerChild child : data.body()) {
- nnWriter.write(child);
- nnWriter.flush();
- }
- }
-}
+++ /dev/null
-/*
- * 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.sal.rest.impl;
-
-import static java.util.Objects.requireNonNull;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.yang.common.XMLNamespace;
-import org.opendaylight.yangtools.yang.data.util.AbstractModuleStringInstanceIdentifierCodec;
-import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-/**
- * Codec for module instance identifiers.
- *
- * @deprecated This class will be replaced by StringModuleInstanceIdentifierCodec from restconf-nb-rfc8040
- */
-@Deprecated
-public final class StringModuleInstanceIdentifierCodec extends AbstractModuleStringInstanceIdentifierCodec {
-
- private final DataSchemaContextTree dataContextTree;
- private final SchemaContext context;
- private final String defaultPrefix;
-
- public StringModuleInstanceIdentifierCodec(final EffectiveModelContext context) {
- this.context = requireNonNull(context);
- this.dataContextTree = DataSchemaContextTree.from(context);
- this.defaultPrefix = "";
- }
-
- StringModuleInstanceIdentifierCodec(final EffectiveModelContext context, final @NonNull String defaultPrefix) {
- this.context = requireNonNull(context);
- this.dataContextTree = DataSchemaContextTree.from(context);
- this.defaultPrefix = defaultPrefix;
- }
-
- @Override
- protected Module moduleForPrefix(final String prefix) {
- if (prefix.isEmpty() && !this.defaultPrefix.isEmpty()) {
- return this.context.findModules(this.defaultPrefix).stream().findFirst().orElse(null);
- } else {
- return this.context.findModules(prefix).stream().findFirst().orElse(null);
- }
- }
-
- @Override
- protected DataSchemaContextTree getDataContextTree() {
- return this.dataContextTree;
- }
-
- @Override
- protected String prefixForNamespace(final XMLNamespace namespace) {
- return this.context.findModules(namespace).stream().findFirst().map(Module::getName).orElse(null);
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.sal.rest.impl;
-
-public class UnsupportedFormatException extends Exception {
-
- private static final long serialVersionUID = -1741388894406313402L;
-
- public UnsupportedFormatException() {
- }
-
- public UnsupportedFormatException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public UnsupportedFormatException(String message) {
- super(message);
- }
-
- public UnsupportedFormatException(Throwable cause) {
- super(cause);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.sal.rest.impl;
-
-@Deprecated(forRemoval = true, since = "2.0.6")
-public final class WriterParameters {
- static final WriterParameters EMPTY = new WriterParametersBuilder().build();
-
- private final Integer depth;
- private final boolean prettyPrint;
-
- private WriterParameters(final WriterParametersBuilder builder) {
- depth = builder.depth;
- prettyPrint = builder.prettyPrint;
- }
-
- public Integer getDepth() {
- return depth;
- }
-
- public boolean isPrettyPrint() {
- return prettyPrint;
- }
-
- @Deprecated(forRemoval = true, since = "2.0.6")
- public static final class WriterParametersBuilder {
- private Integer depth;
- private boolean prettyPrint;
-
- public WriterParametersBuilder setDepth(final int depth) {
- this.depth = depth;
- return this;
- }
-
- public WriterParametersBuilder setPrettyPrint(final boolean prettyPrint) {
- this.prettyPrint = prettyPrint;
- return this;
- }
-
- public WriterParameters build() {
- return new WriterParameters(this);
- }
- }
-}
+++ /dev/null
-/*
- * 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.sal.rest.impl;
-
-import static com.google.common.base.Preconditions.checkState;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.ext.MessageBodyReader;
-import javax.ws.rs.ext.Provider;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.transform.dom.DOMSource;
-import org.opendaylight.netconf.sal.rest.api.Draft02;
-import org.opendaylight.netconf.sal.rest.api.RestconfService;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.util.RestUtil;
-import org.opendaylight.yangtools.util.xml.UntrustedXML;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.common.ErrorType;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.XMLNamespace;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
-import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
-import org.opendaylight.yangtools.yang.model.api.ContainerLike;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-import org.opendaylight.yangtools.yang.model.api.stmt.ListEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-@Provider
-@Consumes({
- Draft02.MediaTypes.DATA + RestconfService.XML,
- Draft02.MediaTypes.OPERATION + RestconfService.XML,
- MediaType.APPLICATION_XML,
- MediaType.TEXT_XML
-})
-public class XmlNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsProvider
- implements MessageBodyReader<NormalizedNodeContext> {
-
- private static final Logger LOG = LoggerFactory.getLogger(XmlNormalizedNodeBodyReader.class);
-
- public XmlNormalizedNodeBodyReader(final ControllerContext controllerContext) {
- super(controllerContext);
- }
-
- @Override
- public boolean isReadable(final Class<?> type, final Type genericType, final Annotation[] annotations,
- final MediaType mediaType) {
- return true;
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- @Override
- public NormalizedNodeContext readFrom(final Class<NormalizedNodeContext> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType,
- final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream) throws
- WebApplicationException {
- try {
- return readFrom(entityStream);
- } catch (final RestconfDocumentedException e) {
- throw e;
- } catch (final Exception e) {
- LOG.debug("Error parsing xml input", e);
- RestconfDocumentedException.throwIfYangError(e);
- throw new RestconfDocumentedException("Error parsing input: " + e.getMessage(), ErrorType.PROTOCOL,
- ErrorTag.MALFORMED_MESSAGE, e);
- }
- }
-
- private NormalizedNodeContext readFrom(final InputStream entityStream) throws IOException, SAXException,
- XMLStreamException, ParserConfigurationException, URISyntaxException {
- final InstanceIdentifierContext path = getInstanceIdentifierContext();
- final Optional<InputStream> nonEmptyInputStreamOptional = RestUtil.isInputStreamEmpty(entityStream);
- if (nonEmptyInputStreamOptional.isEmpty()) {
- // represent empty nopayload input
- return new NormalizedNodeContext(path, null);
- }
-
- final Document doc = UntrustedXML.newDocumentBuilder().parse(nonEmptyInputStreamOptional.get());
- return parse(path, doc);
- }
-
- private NormalizedNodeContext parse(final InstanceIdentifierContext pathContext,final Document doc)
- throws XMLStreamException, IOException, SAXException, URISyntaxException {
- final SchemaNode schemaNodeContext = pathContext.getSchemaNode();
- DataSchemaNode schemaNode;
- final List<PathArgument> iiToDataList = new ArrayList<>();
- Inference inference;
- if (schemaNodeContext instanceof RpcDefinition) {
- schemaNode = ((RpcDefinition) schemaNodeContext).getInput();
- inference = pathContext.inference();
- } else if (schemaNodeContext instanceof DataSchemaNode) {
- schemaNode = (DataSchemaNode) schemaNodeContext;
-
- final String docRootElm = doc.getDocumentElement().getLocalName();
- final XMLNamespace docRootNamespace = XMLNamespace.of(doc.getDocumentElement().getNamespaceURI());
-
- if (isPost()) {
- final var context = pathContext.getSchemaContext();
- final var it = context.findModuleStatements(docRootNamespace).iterator();
- checkState(it.hasNext(), "Failed to find module for %s", docRootNamespace);
- final var qname = QName.create(it.next().localQNameModule(), docRootElm);
-
- final var nodeAndStack = DataSchemaContextTree.from(context)
- .enterPath(pathContext.getInstanceIdentifier()).orElseThrow();
-
- final var stack = nodeAndStack.stack();
- var current = nodeAndStack.node();
- do {
- final var next = current.enterChild(stack, qname);
- checkState(next != null, "Child \"%s\" was not found in parent schema node \"%s\"", qname,
- schemaNode);
- iiToDataList.add(next.getIdentifier());
- schemaNode = next.getDataSchemaNode();
- current = next;
- } while (current.isMixin());
-
- // We need to unwind the last identifier if it a NodeIdentifierWithPredicates, as it does not have
- // any predicates at all. The real identifier is then added below
- if (stack.currentStatement() instanceof ListEffectiveStatement) {
- iiToDataList.remove(iiToDataList.size() - 1);
- }
-
- inference = stack.toInference();
-
- } else {
- // PUT
- final QName scQName = schemaNode.getQName();
- checkState(docRootElm.equals(scQName.getLocalName()) && docRootNamespace.equals(scQName.getNamespace()),
- "Not correct message root element \"%s\", should be \"%s\"", docRootElm, scQName);
- inference = pathContext.inference();
- }
- } else {
- throw new IllegalStateException("Unknown SchemaNode");
- }
-
-
- NormalizedNode parsed;
- final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
- final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
-
- if (schemaNode instanceof ContainerLike || schemaNode instanceof ListSchemaNode
- || schemaNode instanceof LeafSchemaNode) {
- final XmlParserStream xmlParser = XmlParserStream.create(writer, inference);
- xmlParser.traverse(new DOMSource(doc.getDocumentElement()));
- parsed = resultHolder.getResult();
-
- // When parsing an XML source with a list root node
- // the new XML parser always returns a MapNode with one MapEntryNode inside.
- // However, the old XML parser returned a MapEntryNode directly in this place.
- // Therefore we now have to extract the MapEntryNode from the parsed MapNode.
- if (parsed instanceof MapNode) {
- final MapNode mapNode = (MapNode) parsed;
- // extracting the MapEntryNode
- parsed = mapNode.body().iterator().next();
- }
-
- if (schemaNode instanceof ListSchemaNode && isPost()) {
- iiToDataList.add(parsed.getIdentifier());
- }
- } else {
- LOG.warn("Unknown schema node extension {} was not parsed", schemaNode.getClass());
- parsed = null;
- }
-
- return new NormalizedNodeContext(pathContext.withConcatenatedArgs(iiToDataList), parsed);
- }
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2015 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.sal.rest.impl;
-
-import static com.google.common.base.Verify.verify;
-
-import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableList;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Optional;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.ext.MessageBodyReader;
-import javax.ws.rs.ext.Provider;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.transform.dom.DOMSource;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.netconf.sal.rest.api.Draft02;
-import org.opendaylight.netconf.sal.rest.api.RestconfService;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.patch.PatchContext;
-import org.opendaylight.restconf.common.patch.PatchEditOperation;
-import org.opendaylight.restconf.common.patch.PatchEntity;
-import org.opendaylight.restconf.common.util.RestUtil;
-import org.opendaylight.yangtools.util.xml.UntrustedXML;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.common.ErrorType;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.Revision;
-import org.opendaylight.yangtools.yang.common.XMLNamespace;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
-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.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-/**
- * Yang PATCH Reader for XML.
- *
- * @deprecated This class will be replaced by XmlToPatchBodyReader from restconf-nb-rfc8040
- */
-@Deprecated
-@Provider
-@Consumes({Draft02.MediaTypes.PATCH + RestconfService.XML})
-public class XmlToPatchBodyReader extends AbstractIdentifierAwareJaxRsProvider implements
- MessageBodyReader<PatchContext> {
-
- private static final Logger LOG = LoggerFactory.getLogger(XmlToPatchBodyReader.class);
-
- public XmlToPatchBodyReader(final ControllerContext controllerContext) {
- super(controllerContext);
- }
-
- @Override
- public boolean isReadable(final Class<?> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType) {
- return true;
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- @Override
- public PatchContext readFrom(final Class<PatchContext> type, final Type genericType,
- final Annotation[] annotations, final MediaType mediaType,
- final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream)
- throws WebApplicationException {
-
- try {
- final InstanceIdentifierContext path = getInstanceIdentifierContext();
- final Optional<InputStream> nonEmptyInputStreamOptional = RestUtil.isInputStreamEmpty(entityStream);
- if (nonEmptyInputStreamOptional.isEmpty()) {
- // represent empty nopayload input
- return new PatchContext(path, null, null);
- }
-
- final Document doc = UntrustedXML.newDocumentBuilder().parse(nonEmptyInputStreamOptional.get());
- return parse(path, doc);
- } catch (final RestconfDocumentedException e) {
- throw e;
- } catch (final Exception e) {
- LOG.debug("Error parsing xml input", e);
- RestconfDocumentedException.throwIfYangError(e);
- throw new RestconfDocumentedException("Error parsing input: " + e.getMessage(), ErrorType.PROTOCOL,
- ErrorTag.MALFORMED_MESSAGE, e);
- }
- }
-
- private static PatchContext parse(final InstanceIdentifierContext pathContext, final Document doc)
- throws XMLStreamException, IOException, ParserConfigurationException, SAXException, URISyntaxException {
- final List<PatchEntity> resultCollection = new ArrayList<>();
- final String patchId = doc.getElementsByTagName("patch-id").item(0).getFirstChild().getNodeValue();
- final NodeList editNodes = doc.getElementsByTagName("edit");
-
- for (int i = 0; i < editNodes.getLength(); i++) {
- DataSchemaNode schemaNode = (DataSchemaNode) pathContext.getSchemaNode();
- final Element element = (Element) editNodes.item(i);
- final String operation = element.getElementsByTagName("operation").item(0).getFirstChild().getNodeValue();
- final PatchEditOperation oper = PatchEditOperation.valueOf(operation.toUpperCase(Locale.ROOT));
-
- final String editId = element.getElementsByTagName("edit-id").item(0).getFirstChild().getNodeValue();
- final String target = element.getElementsByTagName("target").item(0).getFirstChild().getNodeValue();
- final List<Element> values = readValueNodes(element, oper);
- final Element firstValueElement = values != null ? values.get(0) : null;
-
- // get namespace according to schema node from path context or value
- final String namespace = firstValueElement == null
- ? schemaNode.getQName().getNamespace().toString() : firstValueElement.getNamespaceURI();
-
- // find module according to namespace
- final Module module = pathContext.getSchemaContext().findModules(XMLNamespace.of(namespace)).iterator()
- .next();
-
- // initialize codec + set default prefix derived from module name
- final StringModuleInstanceIdentifierCodec codec = new StringModuleInstanceIdentifierCodec(
- pathContext.getSchemaContext(), module.getName());
-
- // find complete path to target and target schema node
- // target can be also empty (only slash)
- YangInstanceIdentifier targetII;
- final SchemaNode targetNode;
- final Inference inference;
- if (target.equals("/")) {
- targetII = pathContext.getInstanceIdentifier();
- targetNode = pathContext.getSchemaContext();
- inference = pathContext.inference();
- } else {
- targetII = codec.deserialize(codec.serialize(pathContext.getInstanceIdentifier())
- .concat(prepareNonCondXpath(schemaNode, target.replaceFirst("/", ""), firstValueElement,
- namespace,
- module.getQNameModule().getRevision().map(Revision::toString).orElse(null))));
- // move schema node
- final var result = codec.getDataContextTree().enterPath(targetII).orElseThrow();
- schemaNode = result.node().getDataSchemaNode();
-
- final var stack = result.stack();
- inference = stack.toInference();
-
- stack.exit();
- final EffectiveStatement<?, ?> parentStmt = stack.currentStatement();
- verify(parentStmt instanceof SchemaNode, "Unexpected parent %s", parentStmt);
- targetNode = (SchemaNode) parentStmt;
- }
-
- if (targetNode == null) {
- LOG.debug("Target node {} not found in path {} ", target, pathContext.getSchemaNode());
- throw new RestconfDocumentedException("Error parsing input", ErrorType.PROTOCOL,
- ErrorTag.MALFORMED_MESSAGE);
- }
-
- if (oper.isWithValue()) {
- final NormalizedNode parsed;
- if (schemaNode instanceof ContainerSchemaNode || schemaNode instanceof ListSchemaNode) {
- final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
- final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
- final XmlParserStream xmlParser = XmlParserStream.create(writer, inference);
- xmlParser.traverse(new DOMSource(firstValueElement));
- parsed = resultHolder.getResult();
- } else {
- parsed = null;
- }
-
- // for lists allow to manipulate with list items through their parent
- if (targetII.getLastPathArgument() instanceof NodeIdentifierWithPredicates) {
- targetII = targetII.getParent();
- }
-
- resultCollection.add(new PatchEntity(editId, oper, targetII, parsed));
- } else {
- resultCollection.add(new PatchEntity(editId, oper, targetII));
- }
- }
-
- return new PatchContext(pathContext, ImmutableList.copyOf(resultCollection), patchId);
- }
-
- /**
- * Read value nodes.
- *
- * @param element Element of current edit operation
- * @param operation Name of current operation
- * @return List of value elements
- */
- private static List<Element> readValueNodes(final @NonNull Element element,
- final @NonNull PatchEditOperation operation) {
- final Node valueNode = element.getElementsByTagName("value").item(0);
-
- if (operation.isWithValue() && valueNode == null) {
- throw new RestconfDocumentedException("Error parsing input",
- ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
- }
-
- if (!operation.isWithValue() && valueNode != null) {
- throw new RestconfDocumentedException("Error parsing input",
- ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
- }
-
- if (valueNode == null) {
- return null;
- }
-
- final List<Element> result = new ArrayList<>();
- final NodeList childNodes = valueNode.getChildNodes();
- for (int i = 0; i < childNodes.getLength(); i++) {
- if (childNodes.item(i) instanceof Element) {
- result.add((Element) childNodes.item(i));
- }
- }
-
- return result;
- }
-
- /**
- * Prepare non-conditional XPath suitable for deserialization with {@link StringModuleInstanceIdentifierCodec}.
- *
- * @param schemaNode Top schema node
- * @param target Edit operation target
- * @param value Element with value
- * @param namespace Module namespace
- * @param revision Module revision
- * @return Non-conditional XPath
- */
- private static String prepareNonCondXpath(final @NonNull DataSchemaNode schemaNode, final @NonNull String target,
- final @NonNull Element value, final @NonNull String namespace, final @NonNull String revision) {
- final Iterator<String> args = Splitter.on("/").split(target.substring(target.indexOf(':') + 1)).iterator();
-
- final StringBuilder nonCondXpath = new StringBuilder();
- SchemaNode childNode = schemaNode;
-
- while (args.hasNext()) {
- final String s = args.next();
- nonCondXpath.append('/').append(s);
- childNode = ((DataNodeContainer) childNode).getDataChildByName(QName.create(namespace, revision, s));
-
- if (childNode instanceof ListSchemaNode && args.hasNext()) {
- appendKeys(nonCondXpath, ((ListSchemaNode) childNode).getKeyDefinition().iterator(), args);
- }
- }
-
- if (childNode instanceof ListSchemaNode && value != null) {
- final Iterator<String> keyValues = readKeyValues(value,
- ((ListSchemaNode) childNode).getKeyDefinition().iterator());
- appendKeys(nonCondXpath, ((ListSchemaNode) childNode).getKeyDefinition().iterator(), keyValues);
- }
-
- return nonCondXpath.toString();
- }
-
- /**
- * Read value for every list key.
- *
- * @param value Value element
- * @param keys Iterator of list keys names
- * @return Iterator of list keys values
- */
- private static Iterator<String> readKeyValues(final @NonNull Element value, final @NonNull Iterator<QName> keys) {
- final List<String> result = new ArrayList<>();
-
- while (keys.hasNext()) {
- result.add(value.getElementsByTagName(keys.next().getLocalName()).item(0).getFirstChild().getNodeValue());
- }
-
- return result.iterator();
- }
-
- /**
- * Append key name - key value pairs for every list key to {@code nonCondXpath}.
- *
- * @param nonCondXpath Builder for creating non-conditional XPath
- * @param keyNames Iterator of list keys names
- * @param keyValues Iterator of list keys values
- */
- private static void appendKeys(final @NonNull StringBuilder nonCondXpath, final @NonNull Iterator<QName> keyNames,
- final @NonNull Iterator<String> keyValues) {
- while (keyNames.hasNext()) {
- nonCondXpath.append("[").append(keyNames.next().getLocalName()).append("='").append(keyValues.next())
- .append("']");
- }
- }
-}
+++ /dev/null
-/*
- * 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.sal.rest.impl;
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2015 Brocade Communications 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.sal.restconf.api;
-
-import java.util.Optional;
-import javax.ws.rs.core.MultivaluedMap;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.yangtools.yang.common.OperationFailedException;
-
-/**
- * Provides restconf CRUD operations via code with input/output data in JSON format.
- *
- * @author Thomas Pantelis.
- */
-public interface JSONRestconfService {
- /**
- * The data tree root path.
- */
- String ROOT_PATH = null;
-
- /**
- * Issues a restconf PUT request to the configuration data store.
- *
- * @param uriPath the yang instance identifier path, eg "opendaylight-inventory:nodes/node/device-id".
- * To specify the root, use {@link ROOT_PATH}.
- * @param payload the payload data in JSON format.
- * @throws OperationFailedException if the request fails.
- */
- void put(String uriPath, @NonNull String payload) throws OperationFailedException;
-
- /**
- * Issues a restconf POST request to the configuration data store.
- *
- * @param uriPath the yang instance identifier path, eg "opendaylight-inventory:nodes/node/device-id".
- * To specify the root, use {@link ROOT_PATH}.
- * @param payload the payload data in JSON format.
- * @throws OperationFailedException if the request fails.
- */
- void post(String uriPath, @NonNull String payload) throws OperationFailedException;
-
- /**
- * Issues a restconf DELETE request to the configuration data store.
- *
- * @param uriPath the yang instance identifier path, eg "opendaylight-inventory:nodes/node/device-id".
- * To specify the root, use {@link ROOT_PATH}.
- * @throws OperationFailedException if the request fails.
- */
- void delete(String uriPath) throws OperationFailedException;
-
- /**
- * Issues a restconf GET request to the given data store.
- *
- * @param uriPath the yang instance identifier path, eg "opendaylight-inventory:nodes/node/device-id".
- * To specify the root, use {@link ROOT_PATH}.
- * @param datastoreType the data store type to read from.
- * @return an Optional containing the data in JSON format if present.
- * @throws OperationFailedException if the request fails.
- */
- Optional<String> get(String uriPath, LogicalDatastoreType datastoreType)
- throws OperationFailedException;
-
- /**
- * Invokes a yang-defined RPC.
- *
- * @param uriPath the path representing the RPC to invoke, eg "toaster:make-toast".
- * @param input the input in JSON format if the RPC takes input.
- * @return an Optional containing the output in JSON format if the RPC returns output.
- * @throws OperationFailedException if the request fails.
- */
- Optional<String> invokeRpc(@NonNull String uriPath, Optional<String> input) throws OperationFailedException;
-
- /**
- * Issues a restconf PATCH request to the configuration data store.
- *
- * @param uriPath the yang instance identifier path, eg "opendaylight-inventory:nodes/node/device-id".
- * To specify the root, use {@link ROOT_PATH}.
- * @param payload the payload data in JSON format.
- * @return an Optional containing the patch response data in JSON format.
- * @throws OperationFailedException if the request fails.
- */
- Optional<String> patch(@NonNull String uriPath, @NonNull String payload) throws OperationFailedException;
-
- /**
- * Subscribe to a stream.
- * @param identifier the identifier of the stream, e.g., "data-change-event-subscription/neutron:neutron/...
- * ...neutron:ports/datastore=OPERATIONAL/scope=SUBTREE".
- * @param params HTTP query parameters or null.
- * @return On optional containing the JSON response.
- * @throws OperationFailedException if the requests fails.
- */
- Optional<String> subscribeToStream(@NonNull String identifier, MultivaluedMap<String, String> params)
- throws OperationFailedException;
-}
+++ /dev/null
-/*
- * Copyright (c) 2019 Red Hat, 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.sal.restconf.api;
-
-import java.net.InetAddress;
-
-/**
- * Configuration for the RESTCONF server.
- *
- * @author Michael Vorburger.ch
- */
-public interface RestConfConfig {
-
- /**
- * IP interface which the WebSocket server will listen on.
- */
- default InetAddress webSocketAddress() {
- return InetAddress.getLoopbackAddress();
- }
-
- /**
- * TCP port which the WebSocket server will listen on.
- */
- int webSocketPort();
-}
+++ /dev/null
-/*
- * 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.netconf.sal.restconf.impl;
-
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.MoreExecutors;
-import com.google.common.util.concurrent.SettableFuture;
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import java.util.AbstractMap.SimpleImmutableEntry;
-import java.util.Collection;
-import java.util.Map.Entry;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.common.api.ReadFailedException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeReadOperations;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-final class BatchedExistenceCheck {
- private static final AtomicIntegerFieldUpdater<BatchedExistenceCheck> UPDATER =
- AtomicIntegerFieldUpdater.newUpdater(BatchedExistenceCheck.class, "outstanding");
-
- private final SettableFuture<Entry<YangInstanceIdentifier, ReadFailedException>> future = SettableFuture.create();
-
- @SuppressWarnings("unused")
- private volatile int outstanding;
-
- private BatchedExistenceCheck(final int total) {
- this.outstanding = total;
- }
-
- static BatchedExistenceCheck start(final DOMDataTreeReadOperations readTx,
- final LogicalDatastoreType datastore, final YangInstanceIdentifier parentPath,
- final Collection<? extends NormalizedNode> children) {
- final BatchedExistenceCheck ret = new BatchedExistenceCheck(children.size());
- for (NormalizedNode child : children) {
- final YangInstanceIdentifier path = parentPath.node(child.getIdentifier());
- readTx.exists(datastore, path).addCallback(new FutureCallback<Boolean>() {
- @Override
- public void onSuccess(final Boolean result) {
- ret.complete(path, result);
- }
-
- @Override
- @SuppressFBWarnings("BC_UNCONFIRMED_CAST_OF_RETURN_VALUE")
- public void onFailure(final Throwable throwable) {
- final Exception e;
- if (throwable instanceof Exception) {
- e = (Exception) throwable;
- } else {
- e = new ExecutionException(throwable);
- }
-
- ret.complete(path, ReadFailedException.MAPPER.apply(e));
- }
- }, MoreExecutors.directExecutor());
- }
-
- return ret;
- }
-
- Entry<YangInstanceIdentifier, ReadFailedException> getFailure() throws InterruptedException {
- try {
- return future.get();
- } catch (ExecutionException e) {
- // This should never happen
- throw new IllegalStateException(e);
- }
- }
-
- private void complete(final YangInstanceIdentifier childPath, final boolean present) {
- final int count = UPDATER.decrementAndGet(this);
- if (present) {
- future.set(new SimpleImmutableEntry<>(childPath, null));
- } else if (count == 0) {
- future.set(null);
- }
- }
-
- private void complete(final YangInstanceIdentifier childPath, final ReadFailedException cause) {
- UPDATER.decrementAndGet(this);
- future.set(new SimpleImmutableEntry<>(childPath, cause));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2019 Red Hat, 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.sal.restconf.impl;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.inject.Inject;
-import javax.servlet.ServletException;
-import org.opendaylight.mdsal.dom.api.DOMDataBroker;
-import org.opendaylight.mdsal.dom.api.DOMMountPointService;
-import org.opendaylight.mdsal.dom.api.DOMNotificationService;
-import org.opendaylight.mdsal.dom.api.DOMRpcService;
-import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.netconf.sal.rest.impl.RestconfApplication;
-import org.opendaylight.netconf.sal.restconf.api.RestConfConfig;
-import org.opendaylight.netconf.sal.restconf.web.WebInitializer;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
-import org.opendaylight.yangtools.yang.common.Uint16;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Standalone wiring for RESTCONF.
- *
- * <p>ACK: Some lines here were originally inspired by the RestConfWiring class in
- * opendaylight-simple which in turn was inspired by the CommunityRestConf class
- * from lighty.io. The differences include (1) that this class is "pure Java"
- * without depending on any binding framework utility classes; (2) we do not mix
- * bierman02 and rfc8040 for proper modularity; (3) we simply use {@literal @}Inject
- * instead of manual object wiring, where possible.
- *
- * @author Michael Vorburger.ch (see ACK note for history)
- */
-@SuppressWarnings("deprecation")
-// NOT @Singleton, to avoid that the blueprint-maven-plugin generates <bean>, which we don't want for this
-public class Bierman02RestConfWiring {
-
- private static final Logger LOG = LoggerFactory.getLogger(Bierman02RestConfWiring.class);
-
- private final RestconfProviderImpl webSocketServer;
-
- @Inject
- // The point of all the arguments here is simply to make your chosen Dependency Injection (DI) framework init. them
- public Bierman02RestConfWiring(final RestConfConfig config,
- final DOMSchemaService domSchemaService, final DOMMountPointService domMountPointService,
- final DOMRpcService domRpcService, final DOMDataBroker domDataBroker,
- final DOMNotificationService domNotificationService, final ControllerContext controllerContext,
- final RestconfApplication application, final BrokerFacade broker, final RestconfImpl restconf,
- final StatisticsRestconfServiceWrapper stats, final JSONRestconfServiceImpl jsonRestconfServiceImpl,
- final WebInitializer webInitializer) {
-
- // WebSocket
- LOG.info("webSocketAddress = {}, webSocketPort = {}", config.webSocketAddress(), config.webSocketPort());
- IpAddress wsIpAddress = IpAddressBuilder.getDefaultInstance(config.webSocketAddress().getHostAddress());
- this.webSocketServer = new RestconfProviderImpl(stats, wsIpAddress,
- new PortNumber(Uint16.valueOf(config.webSocketPort())));
- }
-
- @PostConstruct
- public void start() throws ServletException {
- this.webSocketServer.start();
- }
-
- @PreDestroy
- public void stop() {
- this.webSocketServer.close();
- }
-}
+++ /dev/null
-/*
- * 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.sal.restconf.impl;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static java.util.Objects.requireNonNull;
-import static org.opendaylight.mdsal.common.api.LogicalDatastoreType.CONFIGURATION;
-import static org.opendaylight.mdsal.common.api.LogicalDatastoreType.OPERATIONAL;
-
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableList;
-import com.google.common.util.concurrent.FluentFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import java.io.Closeable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Optional;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import javax.annotation.PreDestroy;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.ws.rs.core.Response.Status;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.common.api.ReadFailedException;
-import org.opendaylight.mdsal.dom.api.DOMDataBroker;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeService;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeReadOperations;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
-import org.opendaylight.mdsal.dom.api.DOMMountPoint;
-import org.opendaylight.mdsal.dom.api.DOMNotificationListener;
-import org.opendaylight.mdsal.dom.api.DOMNotificationService;
-import org.opendaylight.mdsal.dom.api.DOMRpcResult;
-import org.opendaylight.mdsal.dom.api.DOMRpcService;
-import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.netconf.sal.streams.listeners.ListenerAdapter;
-import org.opendaylight.netconf.sal.streams.listeners.NotificationListenerAdapter;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.errors.RestconfError;
-import org.opendaylight.restconf.common.patch.PatchContext;
-import org.opendaylight.restconf.common.patch.PatchEditOperation;
-import org.opendaylight.restconf.common.patch.PatchEntity;
-import org.opendaylight.restconf.common.patch.PatchStatusContext;
-import org.opendaylight.restconf.common.patch.PatchStatusEntity;
-import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.CreateDataChangeEventSubscriptionInput1.Scope;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.common.ErrorType;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.SystemMapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UserLeafSetNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UserMapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.CollectionNodeBuilder;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.NormalizedNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.data.impl.schema.SchemaAwareBuilders;
-import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode;
-import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Singleton
-public class BrokerFacade implements Closeable {
- private static final Logger LOG = LoggerFactory.getLogger(BrokerFacade.class);
-
- private final ThreadLocal<Boolean> isMounted = new ThreadLocal<>();
- private final DOMNotificationService domNotification;
- private final ControllerContext controllerContext;
- private final DOMDataBroker domDataBroker;
-
- private volatile DOMRpcService rpcService;
-
- @Inject
- public BrokerFacade(final DOMRpcService rpcService, final DOMDataBroker domDataBroker,
- final DOMNotificationService domNotification, final ControllerContext controllerContext) {
- this.rpcService = requireNonNull(rpcService);
- this.domDataBroker = requireNonNull(domDataBroker);
- this.domNotification = requireNonNull(domNotification);
- this.controllerContext = requireNonNull(controllerContext);
- }
-
- /**
- * Factory method.
- *
- * @deprecated Just use
- * {@link #BrokerFacade(DOMRpcService, DOMDataBroker, DOMNotificationService, ControllerContext)}
- * constructor instead.
- */
- @Deprecated
- public static BrokerFacade newInstance(final DOMRpcService rpcService, final DOMDataBroker domDataBroker,
- final DOMNotificationService domNotification, final ControllerContext controllerContext) {
- return new BrokerFacade(rpcService, domDataBroker, domNotification, controllerContext);
- }
-
- @Override
- @PreDestroy
- public void close() {
- }
-
- /**
- * Read config data by path.
- *
- * @param path
- * path of data
- * @return read date
- */
- public NormalizedNode readConfigurationData(final YangInstanceIdentifier path) {
- return readConfigurationData(path, null);
- }
-
- /**
- * Read config data by path.
- *
- * @param path
- * path of data
- * @param withDefa
- * value of with-defaults parameter
- * @return read date
- */
- public NormalizedNode readConfigurationData(final YangInstanceIdentifier path, final String withDefa) {
- try (DOMDataTreeReadTransaction tx = domDataBroker.newReadOnlyTransaction()) {
- return readDataViaTransaction(tx, CONFIGURATION, path, withDefa);
- }
- }
-
- /**
- * Read config data from mount point by path.
- *
- * @param mountPoint
- * mount point for reading data
- * @param path
- * path of data
- * @return read data
- */
- public NormalizedNode readConfigurationData(final DOMMountPoint mountPoint, final YangInstanceIdentifier path) {
- return readConfigurationData(mountPoint, path, null);
- }
-
- /**
- * Read config data from mount point by path.
- *
- * @param mountPoint
- * mount point for reading data
- * @param path
- * path of data
- * @param withDefa
- * value of with-defaults parameter
- * @return read data
- */
- public NormalizedNode readConfigurationData(final DOMMountPoint mountPoint, final YangInstanceIdentifier path,
- final String withDefa) {
- final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
- if (domDataBrokerService.isPresent()) {
- try (DOMDataTreeReadTransaction tx = domDataBrokerService.get().newReadOnlyTransaction()) {
- return readDataViaTransaction(tx, CONFIGURATION, path, withDefa);
- }
- }
- throw dataBrokerUnavailable(path);
- }
-
- /**
- * Read operational data by path.
- *
- * @param path
- * path of data
- * @return read data
- */
- public NormalizedNode readOperationalData(final YangInstanceIdentifier path) {
- try (DOMDataTreeReadTransaction tx = domDataBroker.newReadOnlyTransaction()) {
- return readDataViaTransaction(tx, OPERATIONAL, path);
- }
- }
-
- /**
- * Read operational data from mount point by path.
- *
- * @param mountPoint
- * mount point for reading data
- * @param path
- * path of data
- * @return read data
- */
- public NormalizedNode readOperationalData(final DOMMountPoint mountPoint, final YangInstanceIdentifier path) {
- final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
- if (domDataBrokerService.isPresent()) {
- try (DOMDataTreeReadTransaction tx = domDataBrokerService.get().newReadOnlyTransaction()) {
- return readDataViaTransaction(tx, OPERATIONAL, path);
- }
- }
- throw dataBrokerUnavailable(path);
- }
-
- /**
- * <b>PUT configuration data</b>
- *
- * <p>
- * Prepare result(status) for PUT operation and PUT data via transaction.
- * Return wrapped status and future from PUT.
- *
- * @param globalSchema
- * used by merge parents (if contains list)
- * @param path
- * path of node
- * @param payload
- * input data
- * @param point
- * point
- * @param insert
- * insert
- * @return wrapper of status and future of PUT
- */
- public PutResult commitConfigurationDataPut(final EffectiveModelContext globalSchema,
- final YangInstanceIdentifier path, final NormalizedNode payload, final String insert, final String point) {
- requireNonNull(globalSchema);
- requireNonNull(path);
- requireNonNull(payload);
-
- isMounted.set(false);
- final DOMDataTreeReadWriteTransaction newReadWriteTransaction = domDataBroker.newReadWriteTransaction();
- final Status status = readDataViaTransaction(newReadWriteTransaction, CONFIGURATION, path) != null ? Status.OK
- : Status.CREATED;
- final FluentFuture<? extends CommitInfo> future = putDataViaTransaction(
- newReadWriteTransaction, CONFIGURATION, path, payload, globalSchema, insert, point);
- isMounted.remove();
- return new PutResult(status, future);
- }
-
- /**
- * <b>PUT configuration data (Mount point)</b>
- *
- * <p>
- * Prepare result(status) for PUT operation and PUT data via transaction.
- * Return wrapped status and future from PUT.
- *
- * @param mountPoint
- * mount point for getting transaction for operation and schema
- * context for merging parents(if contains list)
- * @param path
- * path of node
- * @param payload
- * input data
- * @param point
- * point
- * @param insert
- * insert
- * @return wrapper of status and future of PUT
- */
- public PutResult commitMountPointDataPut(final DOMMountPoint mountPoint, final YangInstanceIdentifier path,
- final NormalizedNode payload, final String insert, final String point) {
- requireNonNull(mountPoint);
- requireNonNull(path);
- requireNonNull(payload);
-
- isMounted.set(true);
- final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
- if (domDataBrokerService.isPresent()) {
- final DOMDataTreeReadWriteTransaction newReadWriteTransaction =
- domDataBrokerService.get().newReadWriteTransaction();
- final Status status = readDataViaTransaction(newReadWriteTransaction, CONFIGURATION, path) != null
- ? Status.OK : Status.CREATED;
- final FluentFuture<? extends CommitInfo> future = putDataViaTransaction(
- newReadWriteTransaction, CONFIGURATION, path, payload, modelContext(mountPoint), insert, point);
- isMounted.remove();
- return new PutResult(status, future);
- }
- isMounted.remove();
- throw dataBrokerUnavailable(path);
- }
-
- public PatchStatusContext patchConfigurationDataWithinTransaction(final PatchContext patchContext)
- throws Exception {
- final DOMMountPoint mountPoint = patchContext.getInstanceIdentifierContext().getMountPoint();
-
- // get new transaction and schema context on server or on mounted device
- final EffectiveModelContext schemaContext;
- final DOMDataTreeReadWriteTransaction patchTransaction;
- if (mountPoint == null) {
- schemaContext = patchContext.getInstanceIdentifierContext().getSchemaContext();
- patchTransaction = domDataBroker.newReadWriteTransaction();
- } else {
- schemaContext = modelContext(mountPoint);
-
- final Optional<DOMDataBroker> optional = mountPoint.getService(DOMDataBroker.class);
-
- if (optional.isPresent()) {
- patchTransaction = optional.get().newReadWriteTransaction();
- } else {
- // if mount point does not have broker it is not possible to continue and global error is reported
- LOG.error("Http Patch {} has failed - device {} does not support broker service",
- patchContext.getPatchId(), mountPoint.getIdentifier());
- return new PatchStatusContext(
- patchContext.getPatchId(),
- null,
- false,
- ImmutableList.of(new RestconfError(ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED,
- "DOM data broker service isn't available for mount point " + mountPoint.getIdentifier()))
- );
- }
- }
-
- final List<PatchStatusEntity> editCollection = new ArrayList<>();
- List<RestconfError> editErrors;
- boolean withoutError = true;
-
- for (final PatchEntity patchEntity : patchContext.getData()) {
- final PatchEditOperation operation = patchEntity.getOperation();
- switch (operation) {
- case CREATE:
- if (withoutError) {
- try {
- postDataWithinTransaction(patchTransaction, CONFIGURATION, patchEntity.getTargetNode(),
- patchEntity.getNode(), schemaContext);
- editCollection.add(new PatchStatusEntity(patchEntity.getEditId(), true, null));
- } catch (final RestconfDocumentedException e) {
- LOG.error("Error call http Patch operation {} on target {}",
- operation,
- patchEntity.getTargetNode().toString());
-
- editErrors = new ArrayList<>();
- editErrors.addAll(e.getErrors());
- editCollection.add(new PatchStatusEntity(patchEntity.getEditId(), false, editErrors));
- withoutError = false;
- }
- }
- break;
- case REPLACE:
- if (withoutError) {
- try {
- putDataWithinTransaction(patchTransaction, CONFIGURATION, patchEntity
- .getTargetNode(), patchEntity.getNode(), schemaContext);
- editCollection.add(new PatchStatusEntity(patchEntity.getEditId(), true, null));
- } catch (final RestconfDocumentedException e) {
- LOG.error("Error call http Patch operation {} on target {}",
- operation,
- patchEntity.getTargetNode().toString());
-
- editErrors = new ArrayList<>();
- editErrors.addAll(e.getErrors());
- editCollection.add(new PatchStatusEntity(patchEntity.getEditId(), false, editErrors));
- withoutError = false;
- }
- }
- break;
- case DELETE:
- case REMOVE:
- if (withoutError) {
- try {
- deleteDataWithinTransaction(patchTransaction, CONFIGURATION, patchEntity
- .getTargetNode());
- editCollection.add(new PatchStatusEntity(patchEntity.getEditId(), true, null));
- } catch (final RestconfDocumentedException e) {
- LOG.error("Error call http Patch operation {} on target {}",
- operation,
- patchEntity.getTargetNode().toString());
-
- editErrors = new ArrayList<>();
- editErrors.addAll(e.getErrors());
- editCollection.add(new PatchStatusEntity(patchEntity.getEditId(), false, editErrors));
- withoutError = false;
- }
- }
- break;
- case MERGE:
- if (withoutError) {
- try {
- mergeDataWithinTransaction(patchTransaction, CONFIGURATION, patchEntity.getTargetNode(),
- patchEntity.getNode(), schemaContext);
- editCollection.add(new PatchStatusEntity(patchEntity.getEditId(), true, null));
- } catch (final RestconfDocumentedException e) {
- LOG.error("Error call http Patch operation {} on target {}",
- operation,
- patchEntity.getTargetNode().toString());
-
- editErrors = new ArrayList<>();
- editErrors.addAll(e.getErrors());
- editCollection.add(new PatchStatusEntity(patchEntity.getEditId(), false, editErrors));
- withoutError = false;
- }
- }
- break;
- default:
- LOG.error("Unsupported http Patch operation {} on target {}",
- operation,
- patchEntity.getTargetNode().toString());
- break;
- }
- }
-
- // if errors then cancel transaction and return error status
- if (!withoutError) {
- patchTransaction.cancel();
- return new PatchStatusContext(patchContext.getPatchId(), ImmutableList.copyOf(editCollection), false, null);
- }
-
- // if no errors commit transaction
- final CountDownLatch waiter = new CountDownLatch(1);
- final FluentFuture<? extends CommitInfo> future = patchTransaction.commit();
- final PatchStatusContextHelper status = new PatchStatusContextHelper();
-
- future.addCallback(new FutureCallback<CommitInfo>() {
- @Override
- public void onSuccess(final CommitInfo result) {
- status.setStatus(new PatchStatusContext(patchContext.getPatchId(), ImmutableList.copyOf(editCollection),
- true, null));
- waiter.countDown();
- }
-
- @Override
- public void onFailure(final Throwable throwable) {
- // if commit failed it is global error
- LOG.error("Http Patch {} transaction commit has failed", patchContext.getPatchId());
- status.setStatus(new PatchStatusContext(patchContext.getPatchId(), ImmutableList.copyOf(editCollection),
- false, ImmutableList.of(
- new RestconfError(ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, throwable.getMessage()))));
- waiter.countDown();
- }
- }, MoreExecutors.directExecutor());
-
- waiter.await();
- return status.getStatus();
- }
-
- // POST configuration
- public FluentFuture<? extends CommitInfo> commitConfigurationDataPost(
- final EffectiveModelContext globalSchema, final YangInstanceIdentifier path,
- final NormalizedNode payload, final String insert, final String point) {
- isMounted.set(false);
- FluentFuture<? extends CommitInfo> future =
- postDataViaTransaction(domDataBroker.newReadWriteTransaction(), CONFIGURATION, path, payload,
- globalSchema, insert, point);
- isMounted.remove();
- return future;
- }
-
- public FluentFuture<? extends CommitInfo> commitConfigurationDataPost(
- final DOMMountPoint mountPoint, final YangInstanceIdentifier path, final NormalizedNode payload,
- final String insert, final String point) {
- isMounted.set(true);
- final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
- if (domDataBrokerService.isPresent()) {
- FluentFuture<? extends CommitInfo> future =
- postDataViaTransaction(domDataBrokerService.get().newReadWriteTransaction(), CONFIGURATION, path,
- payload, modelContext(mountPoint), insert, point);
- isMounted.remove();
- return future;
- }
- isMounted.remove();
- throw dataBrokerUnavailable(path);
- }
-
- // DELETE configuration
- public FluentFuture<? extends CommitInfo> commitConfigurationDataDelete(final YangInstanceIdentifier path) {
- return deleteDataViaTransaction(domDataBroker.newReadWriteTransaction(), CONFIGURATION, path);
- }
-
- public FluentFuture<? extends CommitInfo> commitConfigurationDataDelete(
- final DOMMountPoint mountPoint, final YangInstanceIdentifier path) {
- final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
- if (domDataBrokerService.isPresent()) {
- return deleteDataViaTransaction(domDataBrokerService.get().newReadWriteTransaction(), CONFIGURATION, path);
- }
- throw dataBrokerUnavailable(path);
- }
-
- // RPC
- public ListenableFuture<? extends DOMRpcResult> invokeRpc(final @NonNull QName type,
- final @NonNull NormalizedNode input) {
- if (rpcService == null) {
- throw new RestconfDocumentedException(Status.SERVICE_UNAVAILABLE);
- }
- LOG.trace("Invoke RPC {} with input: {}", type, input);
- return rpcService.invokeRpc(type, input);
- }
-
- public void registerToListenDataChanges(final LogicalDatastoreType datastore, final Scope scope,
- final ListenerAdapter listener) {
- if (listener.isListening()) {
- return;
- }
-
- final YangInstanceIdentifier path = listener.getPath();
- DOMDataTreeChangeService changeService = domDataBroker.getExtensions()
- .getInstance(DOMDataTreeChangeService.class);
- if (changeService == null) {
- throw new UnsupportedOperationException("DOMDataBroker does not support the DOMDataTreeChangeService"
- + domDataBroker);
- }
- DOMDataTreeIdentifier root = new DOMDataTreeIdentifier(datastore, path);
- ListenerRegistration<ListenerAdapter> registration =
- changeService.registerDataTreeChangeListener(root, listener);
- listener.setRegistration(registration);
- }
-
- private NormalizedNode readDataViaTransaction(final DOMDataTreeReadOperations transaction,
- final LogicalDatastoreType datastore, final YangInstanceIdentifier path) {
- return readDataViaTransaction(transaction, datastore, path, null);
- }
-
- private NormalizedNode readDataViaTransaction(final DOMDataTreeReadOperations transaction,
- final LogicalDatastoreType datastore, final YangInstanceIdentifier path, final String withDefa) {
- LOG.trace("Read {} via Restconf: {}", datastore.name(), path);
-
- try {
- final Optional<NormalizedNode> optional = transaction.read(datastore, path).get();
- return optional.map(normalizedNode -> withDefa == null ? normalizedNode :
- prepareDataByParamWithDef(normalizedNode, path, withDefa)).orElse(null);
- } catch (InterruptedException e) {
- LOG.warn("Error reading {} from datastore {}", path, datastore.name(), e);
- throw new RestconfDocumentedException("Error reading data.", e);
- } catch (ExecutionException e) {
- LOG.warn("Error reading {} from datastore {}", path, datastore.name(), e);
- throw RestconfDocumentedException.decodeAndThrow("Error reading data.", Throwables.getCauseAs(e,
- ReadFailedException.class));
- }
- }
-
- private NormalizedNode prepareDataByParamWithDef(final NormalizedNode result,
- final YangInstanceIdentifier path, final String withDefa) {
- boolean trim;
- switch (withDefa) {
- case "trim":
- trim = true;
- break;
- case "explicit":
- trim = false;
- break;
- default:
- throw new RestconfDocumentedException("Bad value used with with-defaults parameter : " + withDefa);
- }
-
- final EffectiveModelContext ctx = controllerContext.getGlobalSchema();
- final DataSchemaContextTree baseSchemaCtxTree = DataSchemaContextTree.from(ctx);
- final DataSchemaNode baseSchemaNode = baseSchemaCtxTree.findChild(path).orElseThrow().getDataSchemaNode();
- if (result instanceof ContainerNode) {
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> builder =
- SchemaAwareBuilders.containerBuilder((ContainerSchemaNode) baseSchemaNode);
- buildCont(builder, (ContainerNode) result, baseSchemaCtxTree, path, trim);
- return builder.build();
- }
-
- final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> builder =
- SchemaAwareBuilders.mapEntryBuilder((ListSchemaNode) baseSchemaNode);
- buildMapEntryBuilder(builder, (MapEntryNode) result, baseSchemaCtxTree, path, trim,
- ((ListSchemaNode) baseSchemaNode).getKeyDefinition());
- return builder.build();
- }
-
- private void buildMapEntryBuilder(
- final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> builder,
- final MapEntryNode result, final DataSchemaContextTree baseSchemaCtxTree,
- final YangInstanceIdentifier actualPath, final boolean trim, final List<QName> keys) {
- for (final DataContainerChild child : result.body()) {
- final YangInstanceIdentifier path = actualPath.node(child.getIdentifier());
- final DataSchemaNode childSchema = baseSchemaCtxTree.findChild(path).orElseThrow().getDataSchemaNode();
- if (child instanceof ContainerNode) {
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> childBuilder =
- SchemaAwareBuilders.containerBuilder((ContainerSchemaNode) childSchema);
- buildCont(childBuilder, (ContainerNode) child, baseSchemaCtxTree, path, trim);
- builder.withChild(childBuilder.build());
- } else if (child instanceof MapNode) {
- final CollectionNodeBuilder<MapEntryNode, SystemMapNode> childBuilder =
- SchemaAwareBuilders.mapBuilder((ListSchemaNode) childSchema);
- buildList(childBuilder, (MapNode) child, baseSchemaCtxTree, path, trim,
- ((ListSchemaNode) childSchema).getKeyDefinition());
- builder.withChild(childBuilder.build());
- } else if (child instanceof LeafNode) {
- final Object defaultVal = ((LeafSchemaNode) childSchema).getType().getDefaultValue().orElse(null);
- final Object nodeVal = child.body();
- final NormalizedNodeBuilder<NodeIdentifier, Object, LeafNode<Object>> leafBuilder =
- SchemaAwareBuilders.leafBuilder((LeafSchemaNode) childSchema);
- if (keys.contains(child.getIdentifier().getNodeType())) {
- leafBuilder.withValue(child.body());
- builder.withChild(leafBuilder.build());
- } else {
- if (trim) {
- if (defaultVal == null || !defaultVal.equals(nodeVal)) {
- leafBuilder.withValue(child.body());
- builder.withChild(leafBuilder.build());
- }
- } else {
- if (defaultVal != null && defaultVal.equals(nodeVal)) {
- leafBuilder.withValue(child.body());
- builder.withChild(leafBuilder.build());
- }
- }
- }
- }
- }
- }
-
- private void buildList(final CollectionNodeBuilder<MapEntryNode, SystemMapNode> builder, final MapNode result,
- final DataSchemaContextTree baseSchemaCtxTree, final YangInstanceIdentifier path, final boolean trim,
- final List<QName> keys) {
- for (final MapEntryNode mapEntryNode : result.body()) {
- final YangInstanceIdentifier actualNode = path.node(mapEntryNode.getIdentifier());
- final DataSchemaNode childSchema = baseSchemaCtxTree.findChild(actualNode).orElseThrow()
- .getDataSchemaNode();
- final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder =
- SchemaAwareBuilders.mapEntryBuilder((ListSchemaNode) childSchema);
- buildMapEntryBuilder(mapEntryBuilder, mapEntryNode, baseSchemaCtxTree, actualNode, trim, keys);
- builder.withChild(mapEntryBuilder.build());
- }
- }
-
- private void buildCont(final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> builder,
- final ContainerNode result, final DataSchemaContextTree baseSchemaCtxTree,
- final YangInstanceIdentifier actualPath, final boolean trim) {
- for (final DataContainerChild child : result.body()) {
- final YangInstanceIdentifier path = actualPath.node(child.getIdentifier());
- final DataSchemaNode childSchema = baseSchemaCtxTree.findChild(path).orElseThrow().getDataSchemaNode();
- if (child instanceof ContainerNode) {
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> builderChild =
- SchemaAwareBuilders.containerBuilder((ContainerSchemaNode) childSchema);
- buildCont(builderChild, result, baseSchemaCtxTree, actualPath, trim);
- builder.withChild(builderChild.build());
- } else if (child instanceof MapNode) {
- final CollectionNodeBuilder<MapEntryNode, SystemMapNode> childBuilder =
- SchemaAwareBuilders.mapBuilder((ListSchemaNode) childSchema);
- buildList(childBuilder, (MapNode) child, baseSchemaCtxTree, path, trim,
- ((ListSchemaNode) childSchema).getKeyDefinition());
- builder.withChild(childBuilder.build());
- } else if (child instanceof LeafNode) {
- final Object defaultVal = ((LeafSchemaNode) childSchema).getType().getDefaultValue().orElse(null);
- final Object nodeVal = child.body();
- final NormalizedNodeBuilder<NodeIdentifier, Object, LeafNode<Object>> leafBuilder =
- SchemaAwareBuilders.leafBuilder((LeafSchemaNode) childSchema);
- if (trim) {
- if (defaultVal == null || !defaultVal.equals(nodeVal)) {
- leafBuilder.withValue(child.body());
- builder.withChild(leafBuilder.build());
- }
- } else {
- if (defaultVal != null && defaultVal.equals(nodeVal)) {
- leafBuilder.withValue(child.body());
- builder.withChild(leafBuilder.build());
- }
- }
- }
- }
- }
-
- /**
- * POST data and submit transaction {@link DOMDataReadWriteTransaction}.
- */
- private FluentFuture<? extends CommitInfo> postDataViaTransaction(
- final DOMDataTreeReadWriteTransaction rwTransaction, final LogicalDatastoreType datastore,
- final YangInstanceIdentifier path, final NormalizedNode payload,
- final EffectiveModelContext schemaContext, final String insert, final String point) {
- LOG.trace("POST {} via Restconf: {} with payload {}", datastore.name(), path, payload);
- postData(rwTransaction, datastore, path, payload, schemaContext, insert, point);
- return rwTransaction.commit();
- }
-
- /**
- * POST data and do NOT submit transaction {@link DOMDataReadWriteTransaction}.
- */
- private void postDataWithinTransaction(
- final DOMDataTreeReadWriteTransaction rwTransaction, final LogicalDatastoreType datastore,
- final YangInstanceIdentifier path, final NormalizedNode payload,
- final EffectiveModelContext schemaContext) {
- LOG.trace("POST {} within Restconf Patch: {} with payload {}", datastore.name(), path, payload);
- postData(rwTransaction, datastore, path, payload, schemaContext, null, null);
- }
-
- private void postData(final DOMDataTreeReadWriteTransaction rwTransaction, final LogicalDatastoreType datastore,
- final YangInstanceIdentifier path, final NormalizedNode payload,
- final EffectiveModelContext schemaContext, final String insert, final String point) {
- if (insert == null) {
- makeNormalPost(rwTransaction, datastore, path, payload, schemaContext);
- return;
- }
-
- final DataSchemaNode schemaNode = checkListAndOrderedType(schemaContext, path);
- checkItemDoesNotExists(rwTransaction, datastore, path);
- switch (insert) {
- case "first":
- if (schemaNode instanceof ListSchemaNode) {
- final UserMapNode readList =
- (UserMapNode) this.readConfigurationData(path.getParent().getParent());
- if (readList == null || readList.isEmpty()) {
- simplePostPut(rwTransaction, datastore, path, payload, schemaContext);
- } else {
- rwTransaction.delete(datastore, path.getParent().getParent());
- simplePostPut(rwTransaction, datastore, path, payload, schemaContext);
- makeNormalPost(rwTransaction, datastore, path.getParent().getParent(), readList,
- schemaContext);
- }
- } else {
- final UserLeafSetNode<?> readLeafList =
- (UserLeafSetNode<?>) readConfigurationData(path.getParent());
- if (readLeafList == null || readLeafList.isEmpty()) {
- simplePostPut(rwTransaction, datastore, path, payload, schemaContext);
- } else {
- rwTransaction.delete(datastore, path.getParent());
- simplePostPut(rwTransaction, datastore, path, payload, schemaContext);
- makeNormalPost(rwTransaction, datastore, path.getParent().getParent(), readLeafList,
- schemaContext);
- }
- }
- break;
- case "last":
- simplePostPut(rwTransaction, datastore, path, payload, schemaContext);
- break;
- case "before":
- if (schemaNode instanceof ListSchemaNode) {
- final UserMapNode readList =
- (UserMapNode) this.readConfigurationData(path.getParent().getParent());
- if (readList == null || readList.isEmpty()) {
- simplePostPut(rwTransaction, datastore, path, payload, schemaContext);
- } else {
- insertWithPointListPost(rwTransaction, datastore, path, payload, schemaContext, point,
- readList,
- true);
- }
- } else {
- final UserLeafSetNode<?> readLeafList =
- (UserLeafSetNode<?>) readConfigurationData(path.getParent());
- if (readLeafList == null || readLeafList.isEmpty()) {
- simplePostPut(rwTransaction, datastore, path, payload, schemaContext);
- } else {
- insertWithPointLeafListPost(rwTransaction, datastore, path, payload, schemaContext, point,
- readLeafList, true);
- }
- }
- break;
- case "after":
- if (schemaNode instanceof ListSchemaNode) {
- final UserMapNode readList =
- (UserMapNode) this.readConfigurationData(path.getParent().getParent());
- if (readList == null || readList.isEmpty()) {
- simplePostPut(rwTransaction, datastore, path, payload, schemaContext);
- } else {
- insertWithPointListPost(rwTransaction, datastore, path, payload, schemaContext, point,
- readList,
- false);
- }
- } else {
- final UserLeafSetNode<?> readLeafList =
- (UserLeafSetNode<?>) readConfigurationData(path.getParent());
- if (readLeafList == null || readLeafList.isEmpty()) {
- simplePostPut(rwTransaction, datastore, path, payload, schemaContext);
- } else {
- insertWithPointLeafListPost(rwTransaction, datastore, path, payload, schemaContext, point,
- readLeafList, false);
- }
- }
- break;
- default:
- throw new RestconfDocumentedException(
- "Used bad value of insert parameter. Possible values are first, last, before or after, "
- + "but was: " + insert);
- }
- }
-
- private void insertWithPointLeafListPost(final DOMDataTreeReadWriteTransaction rwTransaction,
- final LogicalDatastoreType datastore, final YangInstanceIdentifier path, final NormalizedNode payload,
- final EffectiveModelContext schemaContext, final String point, final UserLeafSetNode<?> readLeafList,
- final boolean before) {
- rwTransaction.delete(datastore, path.getParent().getParent());
- final InstanceIdentifierContext instanceIdentifier = controllerContext.toInstanceIdentifier(point);
- int lastItemPosition = 0;
- for (final LeafSetEntryNode<?> nodeChild : readLeafList.body()) {
- if (nodeChild.getIdentifier().equals(instanceIdentifier.getInstanceIdentifier().getLastPathArgument())) {
- break;
- }
- lastItemPosition++;
- }
- if (!before) {
- lastItemPosition++;
- }
- int lastInsertedPosition = 0;
- final NormalizedNode emptySubtree = ImmutableNodes.fromInstanceId(schemaContext, path.getParent().getParent());
- rwTransaction.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
- for (final LeafSetEntryNode<?> nodeChild : readLeafList.body()) {
- if (lastInsertedPosition == lastItemPosition) {
- checkItemDoesNotExists(rwTransaction, datastore, path);
- simplePostPut(rwTransaction, datastore, path, payload, schemaContext);
- }
- final YangInstanceIdentifier childPath = path.getParent().getParent().node(nodeChild.getIdentifier());
- checkItemDoesNotExists(rwTransaction, datastore, childPath);
- rwTransaction.put(datastore, childPath, nodeChild);
- lastInsertedPosition++;
- }
- }
-
- private void insertWithPointListPost(final DOMDataTreeReadWriteTransaction rwTransaction,
- final LogicalDatastoreType datastore,
- final YangInstanceIdentifier path, final NormalizedNode payload, final EffectiveModelContext schemaContext,
- final String point, final MapNode readList, final boolean before) {
- rwTransaction.delete(datastore, path.getParent().getParent());
- final InstanceIdentifierContext instanceIdentifier = controllerContext.toInstanceIdentifier(point);
- int lastItemPosition = 0;
- for (final MapEntryNode mapEntryNode : readList.body()) {
- if (mapEntryNode.getIdentifier()
- .equals(instanceIdentifier.getInstanceIdentifier().getLastPathArgument())) {
- break;
- }
- lastItemPosition++;
- }
- if (!before) {
- lastItemPosition++;
- }
- int lastInsertedPosition = 0;
- final NormalizedNode emptySubtree = ImmutableNodes.fromInstanceId(schemaContext, path.getParent().getParent());
- rwTransaction.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
- for (final MapEntryNode mapEntryNode : readList.body()) {
- if (lastInsertedPosition == lastItemPosition) {
- checkItemDoesNotExists(rwTransaction, datastore, path);
- simplePostPut(rwTransaction, datastore, path, payload, schemaContext);
- }
- final YangInstanceIdentifier childPath = path.getParent().getParent().node(mapEntryNode.getIdentifier());
- checkItemDoesNotExists(rwTransaction, datastore, childPath);
- rwTransaction.put(datastore, childPath, mapEntryNode);
- lastInsertedPosition++;
- }
- }
-
- private static DataSchemaNode checkListAndOrderedType(final EffectiveModelContext ctx,
- final YangInstanceIdentifier path) {
- final YangInstanceIdentifier parent = path.getParent();
- final DataSchemaContextNode<?> node = DataSchemaContextTree.from(ctx).findChild(parent).orElseThrow();
- final DataSchemaNode dataSchemaNode = node.getDataSchemaNode();
-
- if (dataSchemaNode instanceof ListSchemaNode) {
- if (!((ListSchemaNode) dataSchemaNode).isUserOrdered()) {
- throw new RestconfDocumentedException("Insert parameter can be used only with ordered-by user list.");
- }
- return dataSchemaNode;
- }
- if (dataSchemaNode instanceof LeafListSchemaNode) {
- if (!((LeafListSchemaNode) dataSchemaNode).isUserOrdered()) {
- throw new RestconfDocumentedException(
- "Insert parameter can be used only with ordered-by user leaf-list.");
- }
- return dataSchemaNode;
- }
- throw new RestconfDocumentedException("Insert parameter can be used only with list or leaf-list");
- }
-
- private void makeNormalPost(final DOMDataTreeReadWriteTransaction rwTransaction,
- final LogicalDatastoreType datastore, final YangInstanceIdentifier path, final NormalizedNode payload,
- final EffectiveModelContext schemaContext) {
- final Collection<? extends NormalizedNode> children;
- if (payload instanceof MapNode) {
- children = ((MapNode) payload).body();
- } else if (payload instanceof LeafSetNode) {
- children = ((LeafSetNode<?>) payload).body();
- } else {
- simplePostPut(rwTransaction, datastore, path, payload, schemaContext);
- return;
- }
-
- final NormalizedNode emptySubtree = ImmutableNodes.fromInstanceId(schemaContext, path);
- if (children.isEmpty()) {
- if (isMounted != null && !isMounted.get()) {
-
- rwTransaction.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()),
- emptySubtree);
- ensureParentsByMerge(datastore, path, rwTransaction, schemaContext);
- }
- return;
- }
-
- // Kick off batch existence check first...
- final BatchedExistenceCheck check = BatchedExistenceCheck.start(rwTransaction, datastore, path, children);
-
- // ... now enqueue modifications. This relies on proper ordering of requests, i.e. these will not affect the
- // result of the existence checks...
- if (isMounted != null && !isMounted.get()) {
-
- rwTransaction.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
- ensureParentsByMerge(datastore, path, rwTransaction, schemaContext);
- }
- for (final NormalizedNode child : children) {
- // FIXME: we really want a create(YangInstanceIdentifier, NormalizedNode) method in the transaction,
- // as that would allow us to skip the existence checks
- rwTransaction.put(datastore, path.node(child.getIdentifier()), child);
- }
-
- // ... finally collect existence checks and abort the transaction if any of them failed.
- final Entry<YangInstanceIdentifier, ReadFailedException> failure;
- try {
- failure = check.getFailure();
- } catch (InterruptedException e) {
- rwTransaction.cancel();
- throw new RestconfDocumentedException("Could not determine the existence of path " + path, e);
- }
-
- if (failure != null) {
- rwTransaction.cancel();
- final ReadFailedException e = failure.getValue();
- if (e == null) {
- throw new RestconfDocumentedException("Data already exists for path: " + failure.getKey(),
- ErrorType.PROTOCOL, ErrorTag.DATA_EXISTS);
- }
-
- throw new RestconfDocumentedException("Could not determine the existence of path " + failure.getKey(), e,
- e.getErrorList());
- }
- }
-
- private void simplePostPut(final DOMDataTreeReadWriteTransaction rwTransaction,
- final LogicalDatastoreType datastore, final YangInstanceIdentifier path, final NormalizedNode payload,
- final EffectiveModelContext schemaContext) {
- checkItemDoesNotExists(rwTransaction, datastore, path);
- if (isMounted != null && !isMounted.get()) {
- ensureParentsByMerge(datastore, path, rwTransaction, schemaContext);
- }
- rwTransaction.put(datastore, path, payload);
- }
-
- private static boolean doesItemExist(final DOMDataTreeReadWriteTransaction rwTransaction,
- final LogicalDatastoreType store, final YangInstanceIdentifier path) {
- try {
- return rwTransaction.exists(store, path).get();
- } catch (InterruptedException e) {
- rwTransaction.cancel();
- throw new RestconfDocumentedException("Could not determine the existence of path " + path, e);
- } catch (ExecutionException e) {
- rwTransaction.cancel();
- throw RestconfDocumentedException.decodeAndThrow("Could not determine the existence of path " + path,
- Throwables.getCauseAs(e, ReadFailedException.class));
- }
- }
-
- /**
- * Check if item already exists. Throws error if it does NOT already exist.
- * @param rwTransaction Current transaction
- * @param store Used datastore
- * @param path Path to item to verify its existence
- */
- private static void checkItemExists(final DOMDataTreeReadWriteTransaction rwTransaction,
- final LogicalDatastoreType store, final YangInstanceIdentifier path) {
- if (!doesItemExist(rwTransaction, store, path)) {
- LOG.trace("Operation via Restconf was not executed because data at {} does not exist", path);
- rwTransaction.cancel();
- throw new RestconfDocumentedException("Data does not exist for path: " + path, ErrorType.PROTOCOL,
- ErrorTag.DATA_MISSING);
- }
- }
-
- /**
- * Check if item does NOT already exist. Throws error if it already exists.
- * @param rwTransaction Current transaction
- * @param store Used datastore
- * @param path Path to item to verify its existence
- */
- private static void checkItemDoesNotExists(final DOMDataTreeReadWriteTransaction rwTransaction,
- final LogicalDatastoreType store, final YangInstanceIdentifier path) {
- if (doesItemExist(rwTransaction, store, path)) {
- LOG.trace("Operation via Restconf was not executed because data at {} already exists", path);
- rwTransaction.cancel();
- throw new RestconfDocumentedException("Data already exists for path: " + path, ErrorType.PROTOCOL,
- ErrorTag.DATA_EXISTS);
- }
- }
-
- /**
- * PUT data and submit {@link DOMDataReadWriteTransaction}.
- *
- * @param point
- * point
- * @param insert
- * insert
- */
- private FluentFuture<? extends CommitInfo> putDataViaTransaction(
- final DOMDataTreeReadWriteTransaction readWriteTransaction, final LogicalDatastoreType datastore,
- final YangInstanceIdentifier path, final NormalizedNode payload,
- final EffectiveModelContext schemaContext, final String insert, final String point) {
- LOG.trace("Put {} via Restconf: {} with payload {}", datastore.name(), path, payload);
- putData(readWriteTransaction, datastore, path, payload, schemaContext, insert, point);
- return readWriteTransaction.commit();
- }
-
- /**
- * PUT data and do NOT submit {@link DOMDataReadWriteTransaction}.
- */
- private void putDataWithinTransaction(
- final DOMDataTreeReadWriteTransaction writeTransaction, final LogicalDatastoreType datastore,
- final YangInstanceIdentifier path, final NormalizedNode payload,
- final EffectiveModelContext schemaContext) {
- LOG.trace("Put {} within Restconf Patch: {} with payload {}", datastore.name(), path, payload);
- putData(writeTransaction, datastore, path, payload, schemaContext, null, null);
- }
-
- // FIXME: This is doing correct put for container and list children, not sure if this will work for choice case
- private void putData(final DOMDataTreeReadWriteTransaction rwTransaction, final LogicalDatastoreType datastore,
- final YangInstanceIdentifier path, final NormalizedNode payload,
- final EffectiveModelContext schemaContext, final String insert, final String point) {
- if (insert == null) {
- makePut(rwTransaction, datastore, path, payload, schemaContext);
- return;
- }
-
- final DataSchemaNode schemaNode = checkListAndOrderedType(schemaContext, path);
- checkItemDoesNotExists(rwTransaction, datastore, path);
- switch (insert) {
- case "first":
- if (schemaNode instanceof ListSchemaNode) {
- final UserMapNode readList = (UserMapNode) this.readConfigurationData(path.getParent());
- if (readList == null || readList.isEmpty()) {
- simplePut(datastore, path, rwTransaction, schemaContext, payload);
- } else {
- rwTransaction.delete(datastore, path.getParent());
- simplePut(datastore, path, rwTransaction, schemaContext, payload);
- makePut(rwTransaction, datastore, path.getParent(), readList, schemaContext);
- }
- } else {
- final UserLeafSetNode<?> readLeafList =
- (UserLeafSetNode<?>) readConfigurationData(path.getParent());
- if (readLeafList == null || readLeafList.isEmpty()) {
- simplePut(datastore, path, rwTransaction, schemaContext, payload);
- } else {
- rwTransaction.delete(datastore, path.getParent());
- simplePut(datastore, path, rwTransaction, schemaContext, payload);
- makePut(rwTransaction, datastore, path.getParent(), readLeafList,
- schemaContext);
- }
- }
- break;
- case "last":
- simplePut(datastore, path, rwTransaction, schemaContext, payload);
- break;
- case "before":
- if (schemaNode instanceof ListSchemaNode) {
- final UserMapNode readList = (UserMapNode) this.readConfigurationData(path.getParent());
- if (readList == null || readList.isEmpty()) {
- simplePut(datastore, path, rwTransaction, schemaContext, payload);
- } else {
- insertWithPointListPut(rwTransaction, datastore, path, payload, schemaContext, point,
- readList, true);
- }
- } else {
- final UserLeafSetNode<?> readLeafList =
- (UserLeafSetNode<?>) readConfigurationData(path.getParent());
- if (readLeafList == null || readLeafList.isEmpty()) {
- simplePut(datastore, path, rwTransaction, schemaContext, payload);
- } else {
- insertWithPointLeafListPut(rwTransaction, datastore, path, payload, schemaContext, point,
- readLeafList, true);
- }
- }
- break;
- case "after":
- if (schemaNode instanceof ListSchemaNode) {
- final UserMapNode readList = (UserMapNode) this.readConfigurationData(path.getParent());
- if (readList == null || readList.isEmpty()) {
- simplePut(datastore, path, rwTransaction, schemaContext, payload);
- } else {
- insertWithPointListPut(rwTransaction, datastore, path, payload, schemaContext, point,
- readList, false);
- }
- } else {
- final UserLeafSetNode<?> readLeafList =
- (UserLeafSetNode<?>) readConfigurationData(path.getParent());
- if (readLeafList == null || readLeafList.isEmpty()) {
- simplePut(datastore, path, rwTransaction, schemaContext, payload);
- } else {
- insertWithPointLeafListPut(rwTransaction, datastore, path, payload, schemaContext, point,
- readLeafList, false);
- }
- }
- break;
- default:
- throw new RestconfDocumentedException(
- "Used bad value of insert parameter. Possible values are first, last, before or after, but was: "
- + insert);
- }
- }
-
- private void insertWithPointLeafListPut(final DOMDataTreeWriteTransaction tx,
- final LogicalDatastoreType datastore, final YangInstanceIdentifier path, final NormalizedNode payload,
- final EffectiveModelContext schemaContext, final String point, final UserLeafSetNode<?> readLeafList,
- final boolean before) {
- tx.delete(datastore, path.getParent());
- final InstanceIdentifierContext instanceIdentifier = controllerContext.toInstanceIdentifier(point);
- int index1 = 0;
- for (final LeafSetEntryNode<?> nodeChild : readLeafList.body()) {
- if (nodeChild.getIdentifier().equals(instanceIdentifier.getInstanceIdentifier().getLastPathArgument())) {
- break;
- }
- index1++;
- }
- if (!before) {
- index1++;
- }
- int index2 = 0;
- final NormalizedNode emptySubtree = ImmutableNodes.fromInstanceId(schemaContext, path.getParent());
- tx.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
- for (final LeafSetEntryNode<?> nodeChild : readLeafList.body()) {
- if (index2 == index1) {
- simplePut(datastore, path, tx, schemaContext, payload);
- }
- final YangInstanceIdentifier childPath = path.getParent().node(nodeChild.getIdentifier());
- tx.put(datastore, childPath, nodeChild);
- index2++;
- }
- }
-
- private void insertWithPointListPut(final DOMDataTreeWriteTransaction tx, final LogicalDatastoreType datastore,
- final YangInstanceIdentifier path, final NormalizedNode payload, final EffectiveModelContext schemaContext,
- final String point, final UserMapNode readList, final boolean before) {
- tx.delete(datastore, path.getParent());
- final InstanceIdentifierContext instanceIdentifier = controllerContext.toInstanceIdentifier(point);
- int index1 = 0;
- for (final MapEntryNode mapEntryNode : readList.body()) {
- if (mapEntryNode.getIdentifier().equals(instanceIdentifier.getInstanceIdentifier().getLastPathArgument())) {
- break;
- }
- index1++;
- }
- if (!before) {
- index1++;
- }
- int index2 = 0;
- final NormalizedNode emptySubtree = ImmutableNodes.fromInstanceId(schemaContext, path.getParent());
- tx.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
- for (final MapEntryNode mapEntryNode : readList.body()) {
- if (index2 == index1) {
- simplePut(datastore, path, tx, schemaContext, payload);
- }
- final YangInstanceIdentifier childPath = path.getParent().node(mapEntryNode.getIdentifier());
- tx.put(datastore, childPath, mapEntryNode);
- index2++;
- }
- }
-
- private void makePut(final DOMDataTreeWriteTransaction tx, final LogicalDatastoreType datastore,
- final YangInstanceIdentifier path, final NormalizedNode payload,
- final EffectiveModelContext schemaContext) {
- if (payload instanceof MapNode) {
- final NormalizedNode emptySubtree = ImmutableNodes.fromInstanceId(schemaContext, path);
- if (isMounted != null && !isMounted.get()) {
- tx.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
- ensureParentsByMerge(datastore, path, tx, schemaContext);
- }
- for (final MapEntryNode child : ((MapNode) payload).body()) {
- final YangInstanceIdentifier childPath = path.node(child.getIdentifier());
- tx.put(datastore, childPath, child);
- }
- } else {
- simplePut(datastore, path, tx, schemaContext, payload);
- }
- }
-
- private void simplePut(final LogicalDatastoreType datastore, final YangInstanceIdentifier path,
- final DOMDataTreeWriteTransaction tx, final EffectiveModelContext schemaContext,
- final NormalizedNode payload) {
- if (isMounted != null && !isMounted.get()) {
- ensureParentsByMerge(datastore, path, tx, schemaContext);
- }
- tx.put(datastore, path, payload);
- }
-
- private static FluentFuture<? extends CommitInfo> deleteDataViaTransaction(
- final DOMDataTreeReadWriteTransaction readWriteTransaction, final LogicalDatastoreType datastore,
- final YangInstanceIdentifier path) {
- LOG.trace("Delete {} via Restconf: {}", datastore.name(), path);
- checkItemExists(readWriteTransaction, datastore, path);
- readWriteTransaction.delete(datastore, path);
- return readWriteTransaction.commit();
- }
-
- private static void deleteDataWithinTransaction(final DOMDataTreeWriteTransaction tx,
- final LogicalDatastoreType datastore, final YangInstanceIdentifier path) {
- LOG.trace("Delete {} within Restconf Patch: {}", datastore.name(), path);
- tx.delete(datastore, path);
- }
-
- private static void mergeDataWithinTransaction(final DOMDataTreeWriteTransaction tx,
- final LogicalDatastoreType datastore, final YangInstanceIdentifier path, final NormalizedNode payload,
- final EffectiveModelContext schemaContext) {
- LOG.trace("Merge {} within Restconf Patch: {} with payload {}", datastore.name(), path, payload);
- ensureParentsByMerge(datastore, path, tx, schemaContext);
-
- // Since YANG Patch provides the option to specify what kind of operation for each edit,
- // OpenDaylight should not change it.
- tx.merge(datastore, path, payload);
- }
-
- public void registerToListenNotification(final NotificationListenerAdapter listener) {
- if (listener.isListening()) {
- return;
- }
-
- final ListenerRegistration<DOMNotificationListener> registration = domNotification
- .registerNotificationListener(listener, listener.getSchemaPath());
-
- listener.setRegistration(registration);
- }
-
- private static void ensureParentsByMerge(final LogicalDatastoreType store,
- final YangInstanceIdentifier normalizedPath, final DOMDataTreeWriteTransaction tx,
- final EffectiveModelContext schemaContext) {
- final List<PathArgument> normalizedPathWithoutChildArgs = new ArrayList<>();
- YangInstanceIdentifier rootNormalizedPath = null;
-
- final Iterator<PathArgument> it = normalizedPath.getPathArguments().iterator();
-
- while (it.hasNext()) {
- final PathArgument pathArgument = it.next();
- if (rootNormalizedPath == null) {
- rootNormalizedPath = YangInstanceIdentifier.create(pathArgument);
- }
-
- if (it.hasNext()) {
- normalizedPathWithoutChildArgs.add(pathArgument);
- }
- }
-
- if (normalizedPathWithoutChildArgs.isEmpty()) {
- return;
- }
-
- checkArgument(rootNormalizedPath != null, "Empty path received");
- tx.merge(store, rootNormalizedPath, ImmutableNodes.fromInstanceId(schemaContext,
- YangInstanceIdentifier.create(normalizedPathWithoutChildArgs)));
- }
-
- private static RestconfDocumentedException dataBrokerUnavailable(final YangInstanceIdentifier path) {
- LOG.warn("DOM data broker service is not available for mount point {}", path);
- return new RestconfDocumentedException("DOM data broker service is not available for mount point " + path);
- }
-
- private static EffectiveModelContext modelContext(final DOMMountPoint mountPoint) {
- return mountPoint.getService(DOMSchemaService.class)
- .flatMap(svc -> Optional.ofNullable(svc.getGlobalContext()))
- .orElse(null);
- }
-
- private static final class PatchStatusContextHelper {
- PatchStatusContext status;
-
- public PatchStatusContext getStatus() {
- return status;
- }
-
- public void setStatus(final PatchStatusContext status) {
- this.status = status;
- }
- }
-}
+++ /dev/null
-/*
- * 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.sal.restconf.impl;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkState;
-import static com.google.common.base.Verify.verify;
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.base.Splitter;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import java.io.Closeable;
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Optional;
-import java.util.concurrent.atomic.AtomicReference;
-import javax.annotation.PreDestroy;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.ws.rs.core.Response.Status;
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.mdsal.dom.api.DOMMountPoint;
-import org.opendaylight.mdsal.dom.api.DOMMountPointService;
-import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
-import org.opendaylight.netconf.sal.rest.api.Draft02;
-import org.opendaylight.netconf.sal.rest.api.Draft02.RestConfModule;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.util.RestUtil;
-import org.opendaylight.yangtools.concepts.IllegalArgumentCodec;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.common.ErrorType;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.QNameModule;
-import org.opendaylight.yangtools.yang.common.Revision;
-import org.opendaylight.yangtools.yang.common.XMLNamespace;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.InstanceIdentifierBuilder;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.model.api.AnyxmlSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
-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.EffectiveModelContextListener;
-import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Singleton
-public final class ControllerContext implements EffectiveModelContextListener, Closeable {
- // FIXME: this should be in md-sal somewhere
- public static final String MOUNT = "yang-ext:mount";
-
- private static final Logger LOG = LoggerFactory.getLogger(ControllerContext.class);
-
- private static final String NULL_VALUE = "null";
-
- private static final String MOUNT_MODULE = "yang-ext";
-
- private static final String MOUNT_NODE = "mount";
-
- private static final Splitter SLASH_SPLITTER = Splitter.on('/');
-
- private final AtomicReference<Map<QName, RpcDefinition>> qnameToRpc = new AtomicReference<>(Collections.emptyMap());
-
- private final DOMMountPointService mountService;
- private final DOMYangTextSourceProvider yangTextSourceProvider;
- private final ListenerRegistration<?> listenerRegistration;
- private volatile EffectiveModelContext globalSchema;
- private volatile DataNormalizer dataNormalizer;
-
- @Inject
- public ControllerContext(final DOMSchemaService schemaService, final DOMMountPointService mountService,
- final DOMSchemaService domSchemaService) {
- this.mountService = mountService;
- yangTextSourceProvider = domSchemaService.getExtensions().getInstance(DOMYangTextSourceProvider.class);
-
- onModelContextUpdated(schemaService.getGlobalContext());
- listenerRegistration = schemaService.registerSchemaContextListener(this);
- }
-
- /**
- * Factory method.
- *
- * @deprecated Just use the
- * {@link #ControllerContext(DOMSchemaService, DOMMountPointService, DOMSchemaService)}
- * constructor instead.
- */
- @Deprecated
- public static ControllerContext newInstance(final DOMSchemaService schemaService,
- final DOMMountPointService mountService, final DOMSchemaService domSchemaService) {
- return new ControllerContext(schemaService, mountService, domSchemaService);
- }
-
- private void setGlobalSchema(final EffectiveModelContext globalSchema) {
- this.globalSchema = globalSchema;
- dataNormalizer = new DataNormalizer(globalSchema);
- }
-
- public DOMYangTextSourceProvider getYangTextSourceProvider() {
- return yangTextSourceProvider;
- }
-
- private void checkPreconditions() {
- if (globalSchema == null) {
- throw new RestconfDocumentedException(Status.SERVICE_UNAVAILABLE);
- }
- }
-
- @Override
- @PreDestroy
- public void close() {
- listenerRegistration.close();
- }
-
- public void setSchemas(final EffectiveModelContext schemas) {
- onModelContextUpdated(schemas);
- }
-
- public InstanceIdentifierContext toInstanceIdentifier(final String restconfInstance) {
- return toIdentifier(restconfInstance, false);
- }
-
- public EffectiveModelContext getGlobalSchema() {
- return globalSchema;
- }
-
- public InstanceIdentifierContext toMountPointIdentifier(final String restconfInstance) {
- return toIdentifier(restconfInstance, true);
- }
-
- private InstanceIdentifierContext toIdentifier(final String restconfInstance,
- final boolean toMountPointIdentifier) {
- checkPreconditions();
-
- if (restconfInstance == null) {
- return InstanceIdentifierContext.ofLocalRoot(globalSchema);
- }
-
- final List<String> pathArgs = urlPathArgsDecode(SLASH_SPLITTER.split(restconfInstance));
- omitFirstAndLastEmptyString(pathArgs);
- if (pathArgs.isEmpty()) {
- return null;
- }
-
- final String first = pathArgs.iterator().next();
- final String startModule = toModuleName(first);
- if (startModule == null) {
- throw new RestconfDocumentedException("First node in URI has to be in format \"moduleName:nodeName\"",
- ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
-
- final Collection<? extends Module> latestModule = globalSchema.findModules(startModule);
- if (latestModule.isEmpty()) {
- throw new RestconfDocumentedException("The module named '" + startModule + "' does not exist.",
- ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
- }
-
- final InstanceIdentifierContext iiWithSchemaNode = collectPathArguments(YangInstanceIdentifier.builder(),
- new ArrayDeque<>(), pathArgs, latestModule.iterator().next(), null, toMountPointIdentifier);
-
- if (iiWithSchemaNode == null) {
- throw new RestconfDocumentedException("URI has bad format", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
-
- return iiWithSchemaNode;
- }
-
- private static List<String> omitFirstAndLastEmptyString(final List<String> list) {
- if (list.isEmpty()) {
- return list;
- }
-
- final String head = list.iterator().next();
- if (head.isEmpty()) {
- list.remove(0);
- }
-
- if (list.isEmpty()) {
- return list;
- }
-
- final String last = list.get(list.size() - 1);
- if (last.isEmpty()) {
- list.remove(list.size() - 1);
- }
-
- return list;
- }
-
- public Module findModuleByName(final String moduleName) {
- checkPreconditions();
- checkArgument(moduleName != null && !moduleName.isEmpty());
- return globalSchema.findModules(moduleName).stream().findFirst().orElse(null);
- }
-
- public static Module findModuleByName(final DOMMountPoint mountPoint, final String moduleName) {
- checkArgument(moduleName != null && mountPoint != null);
-
- final EffectiveModelContext mountPointSchema = getModelContext(mountPoint);
- return mountPointSchema == null ? null
- : mountPointSchema.findModules(moduleName).stream().findFirst().orElse(null);
- }
-
- public Module findModuleByNamespace(final XMLNamespace namespace) {
- checkPreconditions();
- checkArgument(namespace != null);
- return globalSchema.findModules(namespace).stream().findFirst().orElse(null);
- }
-
- public static Module findModuleByNamespace(final DOMMountPoint mountPoint, final XMLNamespace namespace) {
- checkArgument(namespace != null && mountPoint != null);
-
- final EffectiveModelContext mountPointSchema = getModelContext(mountPoint);
- return mountPointSchema == null ? null
- : mountPointSchema.findModules(namespace).stream().findFirst().orElse(null);
- }
-
- public Module findModuleByNameAndRevision(final String name, final Revision revision) {
- checkPreconditions();
- checkArgument(name != null && revision != null);
-
- return globalSchema.findModule(name, revision).orElse(null);
- }
-
- public Module findModuleByNameAndRevision(final DOMMountPoint mountPoint, final String name,
- final Revision revision) {
- checkPreconditions();
- checkArgument(name != null && revision != null && mountPoint != null);
-
- final EffectiveModelContext schemaContext = getModelContext(mountPoint);
- return schemaContext == null ? null : schemaContext.findModule(name, revision).orElse(null);
- }
-
- public DataNodeContainer getDataNodeContainerFor(final YangInstanceIdentifier path) {
- checkPreconditions();
-
- final Iterable<PathArgument> elements = path.getPathArguments();
- final PathArgument head = elements.iterator().next();
- final QName startQName = head.getNodeType();
- final Module initialModule = globalSchema.findModule(startQName.getModule()).orElse(null);
- DataNodeContainer node = initialModule;
- for (final PathArgument element : elements) {
- final QName _nodeType = element.getNodeType();
- final DataSchemaNode potentialNode = childByQName(node, _nodeType);
- if (potentialNode == null || !isListOrContainer(potentialNode)) {
- return null;
- }
- node = (DataNodeContainer) potentialNode;
- }
-
- return node;
- }
-
- public String toFullRestconfIdentifier(final YangInstanceIdentifier path, final DOMMountPoint mount) {
- checkPreconditions();
-
- final Iterable<PathArgument> elements = path.getPathArguments();
- final StringBuilder builder = new StringBuilder();
- final PathArgument head = elements.iterator().next();
- final QName startQName = head.getNodeType();
- final EffectiveModelContext schemaContext;
- if (mount != null) {
- schemaContext = getModelContext(mount);
- } else {
- schemaContext = globalSchema;
- }
- final Module initialModule = schemaContext.findModule(startQName.getModule()).orElse(null);
- DataNodeContainer node = initialModule;
- for (final PathArgument element : elements) {
- if (!(element instanceof AugmentationIdentifier)) {
- final QName _nodeType = element.getNodeType();
- final DataSchemaNode potentialNode = childByQName(node, _nodeType);
- if ((!(element instanceof NodeIdentifier) || !(potentialNode instanceof ListSchemaNode))
- && !(potentialNode instanceof ChoiceSchemaNode)) {
- builder.append(convertToRestconfIdentifier(element, potentialNode, mount));
- if (potentialNode instanceof DataNodeContainer) {
- node = (DataNodeContainer) potentialNode;
- }
- }
- }
- }
-
- return builder.toString();
- }
-
- public String findModuleNameByNamespace(final XMLNamespace namespace) {
- checkPreconditions();
-
- final Module module = findModuleByNamespace(namespace);
- return module == null ? null : module.getName();
- }
-
- public static String findModuleNameByNamespace(final DOMMountPoint mountPoint, final XMLNamespace namespace) {
- final Module module = findModuleByNamespace(mountPoint, namespace);
- return module == null ? null : module.getName();
- }
-
- public XMLNamespace findNamespaceByModuleName(final String moduleName) {
- final Module module = findModuleByName(moduleName);
- return module == null ? null : module.getNamespace();
- }
-
- public static XMLNamespace findNamespaceByModuleName(final DOMMountPoint mountPoint, final String moduleName) {
- final Module module = findModuleByName(mountPoint, moduleName);
- return module == null ? null : module.getNamespace();
- }
-
- public Collection<? extends Module> getAllModules(final DOMMountPoint mountPoint) {
- checkPreconditions();
-
- final EffectiveModelContext schemaContext = mountPoint == null ? null : getModelContext(mountPoint);
- return schemaContext == null ? null : schemaContext.getModules();
- }
-
- public Collection<? extends Module> getAllModules() {
- checkPreconditions();
- return globalSchema.getModules();
- }
-
- private static String toRestconfIdentifier(final EffectiveModelContext context, final QName qname) {
- final Module schema = context.findModule(qname.getModule()).orElse(null);
- return schema == null ? null : schema.getName() + ':' + qname.getLocalName();
- }
-
- public String toRestconfIdentifier(final QName qname, final DOMMountPoint mountPoint) {
- return mountPoint != null ? toRestconfIdentifier(getModelContext(mountPoint), qname)
- : toRestconfIdentifier(qname);
- }
-
- public String toRestconfIdentifier(final QName qname) {
- checkPreconditions();
-
- return toRestconfIdentifier(globalSchema, qname);
- }
-
- public static String toRestconfIdentifier(final DOMMountPoint mountPoint, final QName qname) {
- return mountPoint == null ? null : toRestconfIdentifier(getModelContext(mountPoint), qname);
- }
-
- public Module getRestconfModule() {
- return findModuleByNameAndRevision(Draft02.RestConfModule.NAME, Revision.of(Draft02.RestConfModule.REVISION));
- }
-
- public Entry<SchemaInferenceStack, ContainerSchemaNode> getRestconfModuleErrorsSchemaNode() {
- checkPreconditions();
-
- final var schema = globalSchema;
- final var namespace = QNameModule.create(XMLNamespace.of(Draft02.RestConfModule.NAMESPACE),
- Revision.of(Draft02.RestConfModule.REVISION));
- if (schema.findModule(namespace).isEmpty()) {
- return null;
- }
-
- final var stack = SchemaInferenceStack.of(globalSchema);
- stack.enterGrouping(RestConfModule.ERRORS_QNAME);
- final var stmt = stack.enterSchemaTree(RestConfModule.ERRORS_QNAME);
- verify(stmt instanceof ContainerSchemaNode, "Unexpected statement %s", stmt);
- return Map.entry(stack, (ContainerSchemaNode) stmt);
- }
-
- public DataSchemaNode getRestconfModuleRestConfSchemaNode(final Module inRestconfModule,
- final String schemaNodeName) {
- Module restconfModule = inRestconfModule;
- if (restconfModule == null) {
- restconfModule = getRestconfModule();
- }
-
- if (restconfModule == null) {
- return null;
- }
-
- final Collection<? extends GroupingDefinition> groupings = restconfModule.getGroupings();
- final Iterable<? extends GroupingDefinition> filteredGroups = Iterables.filter(groupings,
- g -> RestConfModule.RESTCONF_GROUPING_SCHEMA_NODE.equals(g.getQName().getLocalName()));
- final GroupingDefinition restconfGrouping = Iterables.getFirst(filteredGroups, null);
-
- final var instanceDataChildrenByName = findInstanceDataChildrenByName(restconfGrouping,
- RestConfModule.RESTCONF_CONTAINER_SCHEMA_NODE);
- final DataSchemaNode restconfContainer = getFirst(instanceDataChildrenByName);
-
- if (RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE.equals(schemaNodeName)) {
- final var instances = findInstanceDataChildrenByName(
- (DataNodeContainer) restconfContainer, RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE);
- return getFirst(instances);
- } else if (RestConfModule.STREAM_LIST_SCHEMA_NODE.equals(schemaNodeName)) {
- var instances = findInstanceDataChildrenByName(
- (DataNodeContainer) restconfContainer, RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE);
- final DataSchemaNode modules = getFirst(instances);
- instances = findInstanceDataChildrenByName((DataNodeContainer) modules,
- RestConfModule.STREAM_LIST_SCHEMA_NODE);
- return getFirst(instances);
- } else if (RestConfModule.MODULES_CONTAINER_SCHEMA_NODE.equals(schemaNodeName)) {
- final var instances = findInstanceDataChildrenByName(
- (DataNodeContainer) restconfContainer, RestConfModule.MODULES_CONTAINER_SCHEMA_NODE);
- return getFirst(instances);
- } else if (RestConfModule.MODULE_LIST_SCHEMA_NODE.equals(schemaNodeName)) {
- var instances = findInstanceDataChildrenByName(
- (DataNodeContainer) restconfContainer, RestConfModule.MODULES_CONTAINER_SCHEMA_NODE);
- final DataSchemaNode modules = getFirst(instances);
- instances = findInstanceDataChildrenByName((DataNodeContainer) modules,
- RestConfModule.MODULE_LIST_SCHEMA_NODE);
- return getFirst(instances);
- } else if (RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE.equals(schemaNodeName)) {
- final var instances = findInstanceDataChildrenByName(
- (DataNodeContainer) restconfContainer, RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE);
- return getFirst(instances);
- }
-
- return null;
- }
-
- public static @Nullable DataSchemaNode getFirst(final List<FoundChild> children) {
- return children.isEmpty() ? null : children.get(0).child;
- }
-
- private static DataSchemaNode childByQName(final ChoiceSchemaNode container, final QName name) {
- for (final CaseSchemaNode caze : container.getCases()) {
- final DataSchemaNode ret = childByQName(caze, name);
- if (ret != null) {
- return ret;
- }
- }
-
- return null;
- }
-
- private static DataSchemaNode childByQName(final CaseSchemaNode container, final QName name) {
- return container.dataChildByName(name);
- }
-
- private static DataSchemaNode childByQName(final ContainerSchemaNode container, final QName name) {
- return dataNodeChildByQName(container, name);
- }
-
- private static DataSchemaNode childByQName(final ListSchemaNode container, final QName name) {
- return dataNodeChildByQName(container, name);
- }
-
- private static DataSchemaNode childByQName(final Module container, final QName name) {
- return dataNodeChildByQName(container, name);
- }
-
- private static DataSchemaNode childByQName(final DataSchemaNode container, final QName name) {
- return null;
- }
-
-
- private static DataSchemaNode childByQName(final Object container, final QName name) {
- if (container instanceof CaseSchemaNode) {
- return childByQName((CaseSchemaNode) container, name);
- } else if (container instanceof ChoiceSchemaNode) {
- return childByQName((ChoiceSchemaNode) container, name);
- } else if (container instanceof ContainerSchemaNode) {
- return childByQName((ContainerSchemaNode) container, name);
- } else if (container instanceof ListSchemaNode) {
- return childByQName((ListSchemaNode) container, name);
- } else if (container instanceof DataSchemaNode) {
- return childByQName((DataSchemaNode) container, name);
- } else if (container instanceof Module) {
- return childByQName((Module) container, name);
- } else {
- throw new IllegalArgumentException("Unhandled parameter types: "
- + Arrays.asList(container, name).toString());
- }
- }
-
- private static DataSchemaNode dataNodeChildByQName(final DataNodeContainer container, final QName name) {
- final DataSchemaNode ret = container.dataChildByName(name);
- if (ret == null) {
- for (final DataSchemaNode node : container.getChildNodes()) {
- if (node instanceof ChoiceSchemaNode) {
- final ChoiceSchemaNode choiceNode = (ChoiceSchemaNode) node;
- final DataSchemaNode childByQName = childByQName(choiceNode, name);
- if (childByQName != null) {
- return childByQName;
- }
- }
- }
- }
- return ret;
- }
-
- private String toUriString(final Object object, final LeafSchemaNode leafNode, final DOMMountPoint mount)
- throws UnsupportedEncodingException {
- final IllegalArgumentCodec<Object, Object> codec = RestCodec.from(leafNode.getType(), mount, this);
- return object == null ? "" : URLEncoder.encode(codec.serialize(object).toString(), StandardCharsets.UTF_8);
- }
-
- @SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", justification = "Unrecognised NullableDecl")
- private InstanceIdentifierContext collectPathArguments(final InstanceIdentifierBuilder builder,
- final Deque<QName> schemaPath, final List<String> strings, final DataNodeContainer parentNode,
- final DOMMountPoint mountPoint, final boolean returnJustMountPoint) {
- requireNonNull(strings);
-
- if (parentNode == null) {
- return null;
- }
-
- if (strings.isEmpty()) {
- return createContext(builder.build(), (DataSchemaNode) parentNode, mountPoint,
- mountPoint != null ? getModelContext(mountPoint) : globalSchema);
- }
-
- final String head = strings.iterator().next();
-
- if (head.isEmpty()) {
- final List<String> remaining = strings.subList(1, strings.size());
- return collectPathArguments(builder, schemaPath, remaining, parentNode, mountPoint, returnJustMountPoint);
- }
-
- final String nodeName = toNodeName(head);
- final String moduleName = toModuleName(head);
-
- DataSchemaNode targetNode = null;
- if (!Strings.isNullOrEmpty(moduleName)) {
- if (MOUNT_MODULE.equals(moduleName) && MOUNT_NODE.equals(nodeName)) {
- if (mountPoint != null) {
- throw new RestconfDocumentedException("Restconf supports just one mount point in URI.",
- ErrorType.APPLICATION, ErrorTag.OPERATION_NOT_SUPPORTED);
- }
-
- if (mountService == null) {
- throw new RestconfDocumentedException(
- "MountService was not found. Finding behind mount points does not work.",
- ErrorType.APPLICATION, ErrorTag.OPERATION_NOT_SUPPORTED);
- }
-
- final YangInstanceIdentifier partialPath = dataNormalizer.toNormalized(builder.build()).getKey();
- final Optional<DOMMountPoint> mountOpt = mountService.getMountPoint(partialPath);
- if (mountOpt.isEmpty()) {
- LOG.debug("Instance identifier to missing mount point: {}", partialPath);
- throw new RestconfDocumentedException("Mount point does not exist.", ErrorType.PROTOCOL,
- ErrorTag.DATA_MISSING);
- }
- final DOMMountPoint mount = mountOpt.get();
-
- final EffectiveModelContext mountPointSchema = getModelContext(mount);
- if (mountPointSchema == null) {
- throw new RestconfDocumentedException("Mount point does not contain any schema with modules.",
- ErrorType.APPLICATION, ErrorTag.UNKNOWN_ELEMENT);
- }
-
- if (returnJustMountPoint || strings.size() == 1) {
- return InstanceIdentifierContext.ofMountPointRoot(mount, mountPointSchema);
- }
-
- final String moduleNameBehindMountPoint = toModuleName(strings.get(1));
- if (moduleNameBehindMountPoint == null) {
- throw new RestconfDocumentedException(
- "First node after mount point in URI has to be in format \"moduleName:nodeName\"",
- ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
-
- final Iterator<? extends Module> it = mountPointSchema.findModules(moduleNameBehindMountPoint)
- .iterator();
- if (!it.hasNext()) {
- throw new RestconfDocumentedException("\"" + moduleNameBehindMountPoint
- + "\" module does not exist in mount point.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
- }
-
- final List<String> subList = strings.subList(1, strings.size());
- return collectPathArguments(YangInstanceIdentifier.builder(), new ArrayDeque<>(), subList, it.next(),
- mount, returnJustMountPoint);
- }
-
- Module module = null;
- if (mountPoint == null) {
- checkPreconditions();
- module = globalSchema.findModules(moduleName).stream().findFirst().orElse(null);
- if (module == null) {
- throw new RestconfDocumentedException("\"" + moduleName + "\" module does not exist.",
- ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
- }
- } else {
- final EffectiveModelContext schemaContext = getModelContext(mountPoint);
- if (schemaContext != null) {
- module = schemaContext.findModules(moduleName).stream().findFirst().orElse(null);
- } else {
- module = null;
- }
- if (module == null) {
- throw new RestconfDocumentedException("\"" + moduleName
- + "\" module does not exist in mount point.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
- }
- }
-
- final var found = findInstanceDataChildByNameAndNamespace(parentNode, nodeName, module.getNamespace());
- if (found == null) {
- if (parentNode instanceof Module) {
- final RpcDefinition rpc;
- if (mountPoint == null) {
- rpc = getRpcDefinition(head, module.getRevision());
- } else {
- rpc = getRpcDefinition(module, toNodeName(head));
- }
- if (rpc != null) {
- final var ctx = mountPoint == null ? globalSchema : getModelContext(mountPoint);
- return InstanceIdentifierContext.ofRpcInput(ctx, rpc, mountPoint);
- }
- }
- throw new RestconfDocumentedException("URI has bad format. Possible reasons:\n" + " 1. \"" + head
- + "\" was not found in parent data node.\n" + " 2. \"" + head
- + "\" is behind mount point. Then it should be in format \"/" + MOUNT + "/" + head + "\".",
- ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
-
- targetNode = found.child;
- schemaPath.addAll(found.intermediate);
- schemaPath.add(targetNode.getQName());
- } else {
- final var potentialSchemaNodes = findInstanceDataChildrenByName(parentNode, nodeName);
- if (potentialSchemaNodes.size() > 1) {
- final StringBuilder strBuilder = new StringBuilder();
- for (var potentialNodeSchema : potentialSchemaNodes) {
- strBuilder.append(" ").append(potentialNodeSchema.child.getQName().getNamespace()).append("\n");
- }
-
- throw new RestconfDocumentedException(
- "URI has bad format. Node \""
- + nodeName + "\" is added as augment from more than one module. "
- + "Therefore the node must have module name "
- + "and it has to be in format \"moduleName:nodeName\"."
- + "\nThe node is added as augment from modules with namespaces:\n"
- + strBuilder.toString(), ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
-
- if (potentialSchemaNodes.isEmpty()) {
- throw new RestconfDocumentedException("\"" + nodeName + "\" in URI was not found in parent data node",
- ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
- }
-
- final var found = potentialSchemaNodes.get(0);
- targetNode = found.child;
- schemaPath.addAll(found.intermediate);
- schemaPath.add(targetNode.getQName());
- }
-
- if (!isListOrContainer(targetNode)) {
- throw new RestconfDocumentedException("URI has bad format. Node \"" + head
- + "\" must be Container or List yang type.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
-
- int consumed = 1;
- if (targetNode instanceof ListSchemaNode) {
- final ListSchemaNode listNode = (ListSchemaNode) targetNode;
- final int keysSize = listNode.getKeyDefinition().size();
- if (strings.size() - consumed < keysSize) {
- throw new RestconfDocumentedException("Missing key for list \"" + listNode.getQName().getLocalName()
- + "\".", ErrorType.PROTOCOL, ErrorTag.DATA_MISSING);
- }
-
- final List<String> uriKeyValues = strings.subList(consumed, consumed + keysSize);
- final HashMap<QName, Object> keyValues = new HashMap<>();
- int index = 0;
- for (final QName key : listNode.getKeyDefinition()) {
- final String uriKeyValue = uriKeyValues.get(index);
- if (uriKeyValue.equals(NULL_VALUE)) {
- throw new RestconfDocumentedException("URI has bad format. List \""
- + listNode.getQName().getLocalName() + "\" cannot contain \"null\" value as a key.",
- ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
-
- final var keyChild = listNode.getDataChildByName(key);
- schemaPath.addLast(keyChild.getQName());
- addKeyValue(keyValues, schemaPath, keyChild, uriKeyValue, mountPoint);
- schemaPath.removeLast();
- index++;
- }
-
- consumed = consumed + index;
- builder.nodeWithKey(targetNode.getQName(), keyValues);
- } else {
- builder.node(targetNode.getQName());
- }
-
- if (targetNode instanceof DataNodeContainer) {
- final List<String> remaining = strings.subList(consumed, strings.size());
- return collectPathArguments(builder, schemaPath, remaining, (DataNodeContainer) targetNode, mountPoint,
- returnJustMountPoint);
- }
-
- return createContext(builder.build(), targetNode, mountPoint,
- mountPoint != null ? getModelContext(mountPoint) : globalSchema);
- }
-
- private static InstanceIdentifierContext createContext(final YangInstanceIdentifier instance,
- final DataSchemaNode dataSchemaNode, final DOMMountPoint mountPoint,
- final EffectiveModelContext schemaContext) {
- final var normalized = new DataNormalizer(schemaContext).toNormalized(instance);
- return InstanceIdentifierContext.ofPath(normalized.getValue(), dataSchemaNode, normalized.getKey(), mountPoint);
- }
-
- public static @Nullable FoundChild findInstanceDataChildByNameAndNamespace(final DataNodeContainer container,
- final String name, final XMLNamespace namespace) {
- requireNonNull(namespace);
-
- for (var node : findInstanceDataChildrenByName(container, name)) {
- if (namespace.equals(node.child.getQName().getNamespace())) {
- return node;
- }
- }
- return null;
- }
-
- public static List<FoundChild> findInstanceDataChildrenByName(final DataNodeContainer container,
- final String name) {
- final List<FoundChild> instantiatedDataNodeContainers = new ArrayList<>();
- collectInstanceDataNodeContainers(instantiatedDataNodeContainers, requireNonNull(container),
- requireNonNull(name), List.of());
- return instantiatedDataNodeContainers;
- }
-
- private static void collectInstanceDataNodeContainers(final List<FoundChild> potentialSchemaNodes,
- final DataNodeContainer container, final String name, final List<QName> intermediate) {
- // We perform two iterations to retain breadth-first ordering
- for (var child : container.getChildNodes()) {
- if (name.equals(child.getQName().getLocalName()) && isInstantiatedDataSchema(child)) {
- potentialSchemaNodes.add(new FoundChild(child, intermediate));
- }
- }
-
- for (var child : container.getChildNodes()) {
- if (child instanceof ChoiceSchemaNode) {
- for (var caze : ((ChoiceSchemaNode) child).getCases()) {
- collectInstanceDataNodeContainers(potentialSchemaNodes, caze, name,
- ImmutableList.<QName>builderWithExpectedSize(intermediate.size() + 2)
- .addAll(intermediate).add(child.getQName()).add(caze.getQName())
- .build());
- }
- }
- }
- }
-
- public static boolean isInstantiatedDataSchema(final DataSchemaNode node) {
- return node instanceof LeafSchemaNode || node instanceof LeafListSchemaNode
- || node instanceof ContainerSchemaNode || node instanceof ListSchemaNode
- || node instanceof AnyxmlSchemaNode;
- }
-
- private void addKeyValue(final HashMap<QName, Object> map, final Deque<QName> schemaPath, final DataSchemaNode node,
- final String uriValue, final DOMMountPoint mountPoint) {
- checkArgument(node instanceof LeafSchemaNode);
-
- final EffectiveModelContext schemaContext = mountPoint == null ? globalSchema : getModelContext(mountPoint);
- final String urlDecoded = urlPathArgDecode(requireNonNull(uriValue));
- TypeDefinition<?> typedef = ((LeafSchemaNode) node).getType();
- final TypeDefinition<?> baseType = RestUtil.resolveBaseTypeFrom(typedef);
- if (baseType instanceof LeafrefTypeDefinition) {
- final var stack = SchemaInferenceStack.of(schemaContext);
- schemaPath.forEach(stack::enterSchemaTree);
- typedef = stack.resolveLeafref((LeafrefTypeDefinition) baseType);
- }
- final IllegalArgumentCodec<Object, Object> codec = RestCodec.from(typedef, mountPoint, this);
- Object decoded = codec.deserialize(urlDecoded);
- String additionalInfo = "";
- if (decoded == null) {
- if (typedef instanceof IdentityrefTypeDefinition) {
- decoded = toQName(schemaContext, urlDecoded);
- additionalInfo =
- "For key which is of type identityref it should be in format module_name:identity_name.";
- }
- }
-
- if (decoded == null) {
- throw new RestconfDocumentedException(uriValue + " from URI can't be resolved. " + additionalInfo,
- ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
-
- map.put(node.getQName(), decoded);
- }
-
- private static String toModuleName(final String str) {
- final int idx = str.indexOf(':');
- if (idx == -1) {
- return null;
- }
-
- // Make sure there is only one occurrence
- if (str.indexOf(':', idx + 1) != -1) {
- return null;
- }
-
- return str.substring(0, idx);
- }
-
- private static String toNodeName(final String str) {
- final int idx = str.indexOf(':');
- if (idx == -1) {
- return str;
- }
-
- // Make sure there is only one occurrence
- if (str.indexOf(':', idx + 1) != -1) {
- return str;
- }
-
- return str.substring(idx + 1);
- }
-
- private QName toQName(final EffectiveModelContext schemaContext, final String name,
- final Optional<Revision> revisionDate) {
- checkPreconditions();
- final String module = toModuleName(name);
- final String node = toNodeName(name);
- final Module m = schemaContext.findModule(module, revisionDate).orElse(null);
- return m == null ? null : QName.create(m.getQNameModule(), node);
- }
-
- private QName toQName(final EffectiveModelContext schemaContext, final String name) {
- checkPreconditions();
- final String module = toModuleName(name);
- final String node = toNodeName(name);
- final Collection<? extends Module> modules = schemaContext.findModules(module);
- return modules.isEmpty() ? null : QName.create(modules.iterator().next().getQNameModule(), node);
- }
-
- private static boolean isListOrContainer(final DataSchemaNode node) {
- return node instanceof ListSchemaNode || node instanceof ContainerSchemaNode;
- }
-
- public RpcDefinition getRpcDefinition(final String name, final Optional<Revision> revisionDate) {
- final QName validName = toQName(globalSchema, name, revisionDate);
- return validName == null ? null : qnameToRpc.get().get(validName);
- }
-
- public RpcDefinition getRpcDefinition(final String name) {
- final QName validName = toQName(globalSchema, name);
- return validName == null ? null : qnameToRpc.get().get(validName);
- }
-
- private static RpcDefinition getRpcDefinition(final Module module, final String rpcName) {
- final QName rpcQName = QName.create(module.getQNameModule(), rpcName);
- for (final RpcDefinition rpcDefinition : module.getRpcs()) {
- if (rpcQName.equals(rpcDefinition.getQName())) {
- return rpcDefinition;
- }
- }
- return null;
- }
-
- @Override
- public void onModelContextUpdated(final EffectiveModelContext context) {
- if (context != null) {
- final Collection<? extends RpcDefinition> defs = context.getOperations();
- final Map<QName, RpcDefinition> newMap = new HashMap<>(defs.size());
-
- for (final RpcDefinition operation : defs) {
- newMap.put(operation.getQName(), operation);
- }
-
- // FIXME: still not completely atomic
- qnameToRpc.set(ImmutableMap.copyOf(newMap));
- setGlobalSchema(context);
- }
- }
-
- private static List<String> urlPathArgsDecode(final Iterable<String> strings) {
- final List<String> decodedPathArgs = new ArrayList<>();
- for (final String pathArg : strings) {
- final String _decode = URLDecoder.decode(pathArg, StandardCharsets.UTF_8);
- decodedPathArgs.add(_decode);
- }
- return decodedPathArgs;
- }
-
- static String urlPathArgDecode(final String pathArg) {
- if (pathArg == null) {
- return null;
- }
- return URLDecoder.decode(pathArg, StandardCharsets.UTF_8);
- }
-
- private String convertToRestconfIdentifier(final PathArgument argument, final DataSchemaNode node,
- final DOMMountPoint mount) {
- if (argument instanceof NodeIdentifier) {
- return convertToRestconfIdentifier((NodeIdentifier) argument, mount);
- } else if (argument instanceof NodeIdentifierWithPredicates && node instanceof ListSchemaNode) {
- return convertToRestconfIdentifierWithPredicates((NodeIdentifierWithPredicates) argument,
- (ListSchemaNode) node, mount);
- } else if (argument != null && node != null) {
- throw new IllegalArgumentException("Conversion of generic path argument is not supported");
- } else {
- throw new IllegalArgumentException("Unhandled parameter types: " + Arrays.asList(argument, node));
- }
- }
-
- private String convertToRestconfIdentifier(final NodeIdentifier argument, final DOMMountPoint node) {
- return "/" + toRestconfIdentifier(argument.getNodeType(), node);
- }
-
- private String convertToRestconfIdentifierWithPredicates(final NodeIdentifierWithPredicates argument,
- final ListSchemaNode node, final DOMMountPoint mount) {
- final QName nodeType = argument.getNodeType();
- final String nodeIdentifier = toRestconfIdentifier(nodeType, mount);
-
- final StringBuilder builder = new StringBuilder().append('/').append(nodeIdentifier).append('/');
-
- final List<QName> keyDefinition = node.getKeyDefinition();
- boolean hasElements = false;
- for (final QName key : keyDefinition) {
- for (final DataSchemaNode listChild : node.getChildNodes()) {
- if (listChild.getQName().equals(key)) {
- if (!hasElements) {
- hasElements = true;
- } else {
- builder.append('/');
- }
-
- checkState(listChild instanceof LeafSchemaNode,
- "List key has to consist of leaves, not %s", listChild);
-
- final Object value = argument.getValue(key);
- try {
- builder.append(toUriString(value, (LeafSchemaNode)listChild, mount));
- } catch (final UnsupportedEncodingException e) {
- LOG.error("Error parsing URI: {}", value, e);
- return null;
- }
- break;
- }
- }
- }
-
- return builder.toString();
- }
-
- public YangInstanceIdentifier toXpathRepresentation(final YangInstanceIdentifier instanceIdentifier) {
- if (dataNormalizer == null) {
- throw new RestconfDocumentedException("Data normalizer isn't set. Normalization isn't possible");
- }
-
- try {
- return dataNormalizer.toLegacy(instanceIdentifier);
- } catch (final DataNormalizationException e) {
- throw new RestconfDocumentedException("Data normalizer failed. Normalization isn't possible", e);
- }
- }
-
- public boolean isNodeMixin(final YangInstanceIdentifier path) {
- final DataNormalizationOperation<?> operation;
- try {
- operation = dataNormalizer.getOperation(path);
- } catch (final DataNormalizationException e) {
- throw new RestconfDocumentedException("Data normalizer failed. Normalization isn't possible", e);
- }
- return operation.isMixin();
- }
-
- private static EffectiveModelContext getModelContext(final DOMMountPoint mountPoint) {
- return mountPoint.getService(DOMSchemaService.class)
- .flatMap(svc -> Optional.ofNullable(svc.getGlobalContext()))
- .orElse(null);
- }
-
- public static final class FoundChild {
- // Intermediate schema tree children, usually empty
- public final @NonNull List<QName> intermediate;
- public final @NonNull DataSchemaNode child;
-
- private FoundChild(final DataSchemaNode child, final List<QName> intermediate) {
- this.child = requireNonNull(child);
- this.intermediate = requireNonNull(intermediate);
- }
- }
-}
+++ /dev/null
-/*
- * 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.sal.restconf.impl;
-
-final class DataNormalizationException extends Exception {
- private static final long serialVersionUID = 1L;
-
- DataNormalizationException(final String message) {
- super(message);
- }
-}
+++ /dev/null
-/*
- * 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.sal.restconf.impl;
-
-import static com.google.common.base.Verify.verifyNotNull;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.yangtools.concepts.Identifiable;
-import org.opendaylight.yangtools.yang.common.Empty;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode;
-import org.opendaylight.yangtools.yang.model.api.AnyxmlSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
-import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerLike;
-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.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.util.EffectiveAugmentationSchema;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
-
-abstract class DataNormalizationOperation<T extends PathArgument> implements Identifiable<T> {
- private final T identifier;
-
- DataNormalizationOperation(final T identifier) {
- this.identifier = identifier;
- }
-
- static DataNormalizationOperation<?> from(final EffectiveModelContext ctx) {
- return new ContainerNormalization(ctx);
- }
-
- @Override
- public T getIdentifier() {
- return identifier;
- }
-
- boolean isMixin() {
- return false;
- }
-
- Set<QName> getQNameIdentifiers() {
- return ImmutableSet.of(identifier.getNodeType());
- }
-
- abstract DataNormalizationOperation<?> getChild(PathArgument child) throws DataNormalizationException;
-
- abstract DataNormalizationOperation<?> getChild(QName child) throws DataNormalizationException;
-
- abstract DataNormalizationOperation<?> enterChild(QName child, SchemaInferenceStack stack)
- throws DataNormalizationException;
-
- abstract DataNormalizationOperation<?> enterChild(PathArgument child, SchemaInferenceStack stack)
- throws DataNormalizationException;
-
- void pushToStack(final SchemaInferenceStack stack) {
- // Accurate for most subclasses
- stack.enterSchemaTree(getIdentifier().getNodeType());
- }
-
- private abstract static class SimpleTypeNormalization<T extends PathArgument>
- extends DataNormalizationOperation<T> {
- SimpleTypeNormalization(final T identifier) {
- super(identifier);
- }
-
- @Override
- final DataNormalizationOperation<?> getChild(final PathArgument child) {
- return null;
- }
-
- @Override
- final DataNormalizationOperation<?> getChild(final QName child) {
- return null;
- }
-
- @Override
- final DataNormalizationOperation<?> enterChild(final QName child, final SchemaInferenceStack stack) {
- return null;
- }
-
- @Override
- final DataNormalizationOperation<?> enterChild(final PathArgument child, final SchemaInferenceStack stack) {
- return null;
- }
- }
-
- private static final class LeafNormalization extends SimpleTypeNormalization<NodeIdentifier> {
- LeafNormalization(final LeafSchemaNode potential) {
- super(new NodeIdentifier(potential.getQName()));
- }
- }
-
- private static final class LeafListEntryNormalization extends SimpleTypeNormalization<NodeWithValue> {
- LeafListEntryNormalization(final LeafListSchemaNode potential) {
- super(new NodeWithValue<>(potential.getQName(), Empty.value()));
- }
-
- @Override
- protected void pushToStack(final SchemaInferenceStack stack) {
- // No-op
- }
- }
-
- private abstract static class DataContainerNormalizationOperation<T extends PathArgument>
- extends DataNormalizationOperation<T> {
- private final DataNodeContainer schema;
- private final Map<QName, DataNormalizationOperation<?>> byQName = new ConcurrentHashMap<>();
- private final Map<PathArgument, DataNormalizationOperation<?>> byArg = new ConcurrentHashMap<>();
-
- DataContainerNormalizationOperation(final T identifier, final DataNodeContainer schema) {
- super(identifier);
- this.schema = schema;
- }
-
- @Override
- DataNormalizationOperation<?> getChild(final PathArgument child) throws DataNormalizationException {
- DataNormalizationOperation<?> potential = byArg.get(child);
- if (potential != null) {
- return potential;
- }
- potential = fromLocalSchema(child);
- return register(potential);
- }
-
- @Override
- DataNormalizationOperation<?> getChild(final QName child) throws DataNormalizationException {
- DataNormalizationOperation<?> potential = byQName.get(child);
- if (potential != null) {
- return potential;
- }
- potential = fromLocalSchemaAndQName(schema, child);
- return register(potential);
- }
-
- @Override
- final DataNormalizationOperation<?> enterChild(final QName child, final SchemaInferenceStack stack)
- throws DataNormalizationException {
- return pushToStack(getChild(child), stack);
- }
-
- @Override
- final DataNormalizationOperation<?> enterChild(final PathArgument child, final SchemaInferenceStack stack)
- throws DataNormalizationException {
- return pushToStack(getChild(child), stack);
- }
-
- private static DataNormalizationOperation<?> pushToStack(final DataNormalizationOperation<?> child,
- final SchemaInferenceStack stack) {
- if (child != null) {
- child.pushToStack(stack);
- }
- return child;
- }
-
- private DataNormalizationOperation<?> fromLocalSchema(final PathArgument child)
- throws DataNormalizationException {
- if (child instanceof AugmentationIdentifier) {
- return fromSchemaAndQNameChecked(schema, ((AugmentationIdentifier) child).getPossibleChildNames()
- .iterator().next());
- }
- return fromSchemaAndQNameChecked(schema, child.getNodeType());
- }
-
- DataNormalizationOperation<?> fromLocalSchemaAndQName(final DataNodeContainer schema2,
- final QName child) throws DataNormalizationException {
- return fromSchemaAndQNameChecked(schema2, child);
- }
-
- private DataNormalizationOperation<?> register(final DataNormalizationOperation<?> potential) {
- if (potential != null) {
- byArg.put(potential.getIdentifier(), potential);
- for (final QName qname : potential.getQNameIdentifiers()) {
- byQName.put(qname, potential);
- }
- }
- return potential;
- }
-
- private static DataNormalizationOperation<?> fromSchemaAndQNameChecked(final DataNodeContainer schema,
- final QName child) throws DataNormalizationException {
-
- final DataSchemaNode result = findChildSchemaNode(schema, child);
- if (result == null) {
- throw new DataNormalizationException(String.format(
- "Supplied QName %s is not valid according to schema %s, potential children nodes: %s", child,
- schema,schema.getChildNodes()));
- }
-
- // We try to look up if this node was added by augmentation
- if (schema instanceof DataSchemaNode && result.isAugmenting()) {
- return fromAugmentation(schema, (AugmentationTarget) schema, result);
- }
- return fromDataSchemaNode(result);
- }
- }
-
- private static final class ListItemNormalization extends
- DataContainerNormalizationOperation<NodeIdentifierWithPredicates> {
- ListItemNormalization(final NodeIdentifierWithPredicates identifier, final ListSchemaNode schema) {
- super(identifier, schema);
- }
-
- @Override
- protected void pushToStack(final SchemaInferenceStack stack) {
- // No-op
- }
- }
-
- private static final class UnkeyedListItemNormalization
- extends DataContainerNormalizationOperation<NodeIdentifier> {
- UnkeyedListItemNormalization(final ListSchemaNode schema) {
- super(new NodeIdentifier(schema.getQName()), schema);
- }
-
- @Override
- protected void pushToStack(final SchemaInferenceStack stack) {
- // No-op
- }
- }
-
- private static final class ContainerNormalization extends DataContainerNormalizationOperation<NodeIdentifier> {
- ContainerNormalization(final ContainerLike schema) {
- super(new NodeIdentifier(schema.getQName()), schema);
- }
- }
-
- private abstract static class MixinNormalizationOp<T extends PathArgument> extends DataNormalizationOperation<T> {
- MixinNormalizationOp(final T identifier) {
- super(identifier);
- }
-
- @Override
- final boolean isMixin() {
- return true;
- }
- }
-
- private abstract static class ListLikeNormalizationOp<T extends PathArgument> extends MixinNormalizationOp<T> {
- ListLikeNormalizationOp(final T identifier) {
- super(identifier);
- }
-
- @Override
- protected final DataNormalizationOperation<?> enterChild(final QName child, final SchemaInferenceStack stack)
- throws DataNormalizationException {
- // Stack is already pointing to the corresponding statement, now we are just working with the child
- return getChild(child);
- }
-
- @Override
- protected final DataNormalizationOperation<?> enterChild(final PathArgument child,
- final SchemaInferenceStack stack) throws DataNormalizationException {
- return getChild(child);
- }
- }
-
- private static final class LeafListMixinNormalization extends ListLikeNormalizationOp<NodeIdentifier> {
- private final DataNormalizationOperation<?> innerOp;
-
- LeafListMixinNormalization(final LeafListSchemaNode potential) {
- super(new NodeIdentifier(potential.getQName()));
- innerOp = new LeafListEntryNormalization(potential);
- }
-
- @Override
- DataNormalizationOperation<?> getChild(final PathArgument child) {
- if (child instanceof NodeWithValue) {
- return innerOp;
- }
- return null;
- }
-
- @Override
- DataNormalizationOperation<?> getChild(final QName child) {
- if (getIdentifier().getNodeType().equals(child)) {
- return innerOp;
- }
- return null;
- }
- }
-
- private static final class AugmentationNormalization
- extends DataContainerNormalizationOperation<AugmentationIdentifier> {
-
- AugmentationNormalization(final AugmentationSchemaNode augmentation, final DataNodeContainer schema) {
- super(DataSchemaContextNode.augmentationIdentifierFrom(augmentation),
- new EffectiveAugmentationSchema(augmentation, schema));
- }
-
- @Override
- boolean isMixin() {
- return true;
- }
-
- @Override
- DataNormalizationOperation<?> fromLocalSchemaAndQName(final DataNodeContainer schema, final QName child) {
- final DataSchemaNode result = findChildSchemaNode(schema, child);
- if (result == null) {
- return null;
- }
-
- // We try to look up if this node was added by augmentation
- if (schema instanceof DataSchemaNode && result.isAugmenting()) {
- return fromAugmentation(schema, (AugmentationTarget) schema, result);
- }
- return fromDataSchemaNode(result);
- }
-
- @Override
- Set<QName> getQNameIdentifiers() {
- return getIdentifier().getPossibleChildNames();
- }
-
- @Override
- void pushToStack(final SchemaInferenceStack stack) {
- // No-op
- }
- }
-
- private static final class MapMixinNormalization extends ListLikeNormalizationOp<NodeIdentifier> {
- private final ListItemNormalization innerNode;
-
- MapMixinNormalization(final ListSchemaNode list) {
- super(new NodeIdentifier(list.getQName()));
- innerNode = new ListItemNormalization(NodeIdentifierWithPredicates.of(list.getQName()), list);
- }
-
- @Override
- DataNormalizationOperation<?> getChild(final PathArgument child) {
- if (child.getNodeType().equals(getIdentifier().getNodeType())) {
- return innerNode;
- }
- return null;
- }
-
- @Override
- DataNormalizationOperation<?> getChild(final QName child) {
- if (getIdentifier().getNodeType().equals(child)) {
- return innerNode;
- }
- return null;
- }
- }
-
- private static final class UnkeyedListMixinNormalization extends ListLikeNormalizationOp<NodeIdentifier> {
- private final UnkeyedListItemNormalization innerNode;
-
- UnkeyedListMixinNormalization(final ListSchemaNode list) {
- super(new NodeIdentifier(list.getQName()));
- innerNode = new UnkeyedListItemNormalization(list);
- }
-
- @Override
- DataNormalizationOperation<?> getChild(final PathArgument child) {
- if (child.getNodeType().equals(getIdentifier().getNodeType())) {
- return innerNode;
- }
- return null;
- }
-
- @Override
- DataNormalizationOperation<?> getChild(final QName child) {
- if (getIdentifier().getNodeType().equals(child)) {
- return innerNode;
- }
- return null;
- }
- }
-
- private static final class ChoiceNodeNormalization extends MixinNormalizationOp<NodeIdentifier> {
- private final ImmutableMap<QName, DataNormalizationOperation<?>> byQName;
- private final ImmutableMap<PathArgument, DataNormalizationOperation<?>> byArg;
- private final ImmutableMap<DataNormalizationOperation<?>, QName> childToCase;
-
- ChoiceNodeNormalization(final ChoiceSchemaNode schema) {
- super(new NodeIdentifier(schema.getQName()));
- ImmutableMap.Builder<DataNormalizationOperation<?>, QName> childToCaseBuilder = ImmutableMap.builder();
- final ImmutableMap.Builder<QName, DataNormalizationOperation<?>> byQNameBuilder = ImmutableMap.builder();
- final ImmutableMap.Builder<PathArgument, DataNormalizationOperation<?>> byArgBuilder =
- ImmutableMap.builder();
-
- for (final CaseSchemaNode caze : schema.getCases()) {
- for (final DataSchemaNode cazeChild : caze.getChildNodes()) {
- final DataNormalizationOperation<?> childOp = fromDataSchemaNode(cazeChild);
- byArgBuilder.put(childOp.getIdentifier(), childOp);
- childToCaseBuilder.put(childOp, caze.getQName());
- for (final QName qname : childOp.getQNameIdentifiers()) {
- byQNameBuilder.put(qname, childOp);
- }
- }
- }
- childToCase = childToCaseBuilder.build();
- byQName = byQNameBuilder.build();
- byArg = byArgBuilder.build();
- }
-
- @Override
- DataNormalizationOperation<?> getChild(final PathArgument child) {
- return byArg.get(child);
- }
-
- @Override
- DataNormalizationOperation<?> getChild(final QName child) {
- return byQName.get(child);
- }
-
- @Override
- Set<QName> getQNameIdentifiers() {
- return byQName.keySet();
- }
-
- @Override
- DataNormalizationOperation<?> enterChild(final QName child, final SchemaInferenceStack stack) {
- return pushToStack(getChild(child), stack);
- }
-
- @Override
- DataNormalizationOperation<?> enterChild(final PathArgument child, final SchemaInferenceStack stack) {
- return pushToStack(getChild(child), stack);
- }
-
- @Override
- void pushToStack(final SchemaInferenceStack stack) {
- stack.enterChoice(getIdentifier().getNodeType());
- }
-
- private DataNormalizationOperation<?> pushToStack(final DataNormalizationOperation<?> child,
- final SchemaInferenceStack stack) {
- if (child != null) {
- final var caseName = verifyNotNull(childToCase.get(child), "No case statement for %s in %s", child,
- this);
- stack.enterSchemaTree(caseName);
- child.pushToStack(stack);
- }
- return child;
- }
- }
-
- private static final class AnyxmlNormalization extends SimpleTypeNormalization<NodeIdentifier> {
- AnyxmlNormalization(final AnyxmlSchemaNode schema) {
- super(new NodeIdentifier(schema.getQName()));
- }
- }
-
- private static @Nullable DataSchemaNode findChildSchemaNode(final DataNodeContainer parent, final QName child) {
- final DataSchemaNode potential = parent.dataChildByName(child);
- return potential != null ? potential : findChoice(parent, child);
- }
-
- private static @Nullable ChoiceSchemaNode findChoice(final DataNodeContainer parent, final QName child) {
- for (final ChoiceSchemaNode choice : Iterables.filter(parent.getChildNodes(), ChoiceSchemaNode.class)) {
- for (final CaseSchemaNode caze : choice.getCases()) {
- if (findChildSchemaNode(caze, child) != null) {
- return choice;
- }
- }
- }
- return null;
- }
-
- /**
- * Returns a DataNormalizationOperation for provided child node.
- *
- * <p>
- * If supplied child is added by Augmentation this operation returns
- * a DataNormalizationOperation for augmentation,
- * otherwise returns a DataNormalizationOperation for child as
- * call for {@link #fromDataSchemaNode(DataSchemaNode)}.
- */
- private static DataNormalizationOperation<?> fromAugmentation(final DataNodeContainer parent,
- final AugmentationTarget parentAug, final DataSchemaNode child) {
- for (final AugmentationSchemaNode aug : parentAug.getAvailableAugmentations()) {
- if (aug.dataChildByName(child.getQName()) != null) {
- return new AugmentationNormalization(aug, parent);
- }
- }
- return fromDataSchemaNode(child);
- }
-
- static DataNormalizationOperation<?> fromDataSchemaNode(final DataSchemaNode potential) {
- if (potential instanceof ContainerSchemaNode) {
- return new ContainerNormalization((ContainerSchemaNode) potential);
- } else if (potential instanceof ListSchemaNode) {
- return fromListSchemaNode((ListSchemaNode) potential);
- } else if (potential instanceof LeafSchemaNode) {
- return new LeafNormalization((LeafSchemaNode) potential);
- } else if (potential instanceof ChoiceSchemaNode) {
- return new ChoiceNodeNormalization((ChoiceSchemaNode) potential);
- } else if (potential instanceof LeafListSchemaNode) {
- return new LeafListMixinNormalization((LeafListSchemaNode) potential);
- } else if (potential instanceof AnyxmlSchemaNode) {
- return new AnyxmlNormalization((AnyxmlSchemaNode) potential);
- }
- return null;
- }
-
- private static DataNormalizationOperation<?> fromListSchemaNode(final ListSchemaNode potential) {
- if (potential.getKeyDefinition().isEmpty()) {
- return new UnkeyedListMixinNormalization(potential);
- }
- return new MapMixinNormalization(potential);
- }
-}
+++ /dev/null
-/*
- * 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.sal.restconf.impl;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.collect.ImmutableList;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
-
-class DataNormalizer {
- private final DataNormalizationOperation<?> operation;
- private final EffectiveModelContext context;
-
- DataNormalizer(final EffectiveModelContext ctx) {
- context = requireNonNull(ctx);
- operation = DataNormalizationOperation.from(ctx);
- }
-
- Entry<YangInstanceIdentifier, SchemaInferenceStack> toNormalized(final YangInstanceIdentifier legacy) {
- List<PathArgument> normalizedArgs = new ArrayList<>();
-
- DataNormalizationOperation<?> currentOp = operation;
- Iterator<PathArgument> arguments = legacy.getPathArguments().iterator();
- SchemaInferenceStack stack = SchemaInferenceStack.of(context);
-
- try {
- while (arguments.hasNext()) {
- PathArgument legacyArg = arguments.next();
- currentOp = currentOp.enterChild(legacyArg, stack);
- checkArgument(currentOp != null,
- "Legacy Instance Identifier %s is not correct. Normalized Instance Identifier so far %s",
- legacy, normalizedArgs);
- while (currentOp.isMixin()) {
- normalizedArgs.add(currentOp.getIdentifier());
- currentOp = currentOp.enterChild(legacyArg.getNodeType(), stack);
- }
- normalizedArgs.add(legacyArg);
- }
- } catch (DataNormalizationException e) {
- throw new IllegalArgumentException("Failed to normalize path " + legacy, e);
- }
-
- return Map.entry(YangInstanceIdentifier.create(normalizedArgs), stack);
- }
-
- DataNormalizationOperation<?> getOperation(final YangInstanceIdentifier legacy)
- throws DataNormalizationException {
- DataNormalizationOperation<?> currentOp = operation;
-
- for (PathArgument pathArgument : legacy.getPathArguments()) {
- currentOp = currentOp.getChild(pathArgument);
- }
- return currentOp;
- }
-
- YangInstanceIdentifier toLegacy(final YangInstanceIdentifier normalized) throws DataNormalizationException {
- ImmutableList.Builder<PathArgument> legacyArgs = ImmutableList.builder();
- DataNormalizationOperation<?> currentOp = operation;
- for (PathArgument normalizedArg : normalized.getPathArguments()) {
- currentOp = currentOp.getChild(normalizedArg);
- if (!currentOp.isMixin()) {
- legacyArgs.add(normalizedArg);
- }
- }
- return YangInstanceIdentifier.create(legacyArgs.build());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Brocade Communications 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.sal.restconf.impl;
-
-import static java.util.Objects.requireNonNull;
-
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.annotation.Annotation;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-import java.util.Optional;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedHashMap;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.UriInfo;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.netconf.sal.rest.api.RestconfService;
-import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.rest.impl.JsonToPatchBodyReader;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeJsonBodyWriter;
-import org.opendaylight.netconf.sal.rest.impl.PatchJsonBodyWriter;
-import org.opendaylight.netconf.sal.restconf.api.JSONRestconfService;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.errors.RestconfError;
-import org.opendaylight.restconf.common.patch.PatchContext;
-import org.opendaylight.restconf.common.patch.PatchStatusContext;
-import org.opendaylight.restconf.common.util.SimpleUriInfo;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.common.OperationFailedException;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Implementation of the JSONRestconfService interface using the restconf Draft02 implementation.
- *
- * @author Thomas Pantelis
- * @deprecated Replaced by {JSONRestconfServiceRfc8040Impl from restconf-nb-rfc8040
- */
-@Singleton
-@Deprecated
-public class JSONRestconfServiceImpl implements JSONRestconfService {
- private static final Logger LOG = LoggerFactory.getLogger(JSONRestconfServiceImpl.class);
-
- private static final Annotation[] EMPTY_ANNOTATIONS = new Annotation[0];
-
- private final ControllerContext controllerContext;
- private final RestconfService restconfService;
-
- @Inject
- public JSONRestconfServiceImpl(final ControllerContext controllerContext, final RestconfImpl restconfService) {
- this.controllerContext = controllerContext;
- this.restconfService = restconfService;
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- @Override
- public void put(final String uriPath, final String payload) throws OperationFailedException {
- requireNonNull(payload, "payload can't be null");
-
- LOG.debug("put: uriPath: {}, payload: {}", uriPath, payload);
-
- final InputStream entityStream = new ByteArrayInputStream(payload.getBytes(StandardCharsets.UTF_8));
- final NormalizedNodeContext context = JsonNormalizedNodeBodyReader.readFrom(uriPath, entityStream, false,
- controllerContext);
-
- LOG.debug("Parsed YangInstanceIdentifier: {}", context.getInstanceIdentifierContext().getInstanceIdentifier());
- LOG.debug("Parsed NormalizedNode: {}", context.getData());
-
- try {
- restconfService.updateConfigurationData(uriPath, context, new SimpleUriInfo(uriPath));
- } catch (final Exception e) {
- propagateExceptionAs(uriPath, e, "PUT");
- }
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- @Override
- public void post(final String uriPath, final String payload) throws OperationFailedException {
- requireNonNull(payload, "payload can't be null");
-
- LOG.debug("post: uriPath: {}, payload: {}", uriPath, payload);
-
- final InputStream entityStream = new ByteArrayInputStream(payload.getBytes(StandardCharsets.UTF_8));
- final NormalizedNodeContext context = JsonNormalizedNodeBodyReader.readFrom(uriPath, entityStream, true,
- controllerContext);
-
- LOG.debug("Parsed YangInstanceIdentifier: {}", context.getInstanceIdentifierContext().getInstanceIdentifier());
- LOG.debug("Parsed NormalizedNode: {}", context.getData());
-
- try {
- restconfService.createConfigurationData(uriPath, context, new SimpleUriInfo(uriPath));
- } catch (final Exception e) {
- propagateExceptionAs(uriPath, e, "POST");
- }
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- @Override
- public void delete(final String uriPath) throws OperationFailedException {
- LOG.debug("delete: uriPath: {}", uriPath);
-
- try {
- restconfService.deleteConfigurationData(uriPath);
- } catch (final Exception e) {
- propagateExceptionAs(uriPath, e, "DELETE");
- }
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- @Override
- public Optional<String> get(final String uriPath, final LogicalDatastoreType datastoreType)
- throws OperationFailedException {
- LOG.debug("get: uriPath: {}", uriPath);
-
- try {
- NormalizedNodeContext readData;
- final SimpleUriInfo uriInfo = new SimpleUriInfo(uriPath);
- if (datastoreType == LogicalDatastoreType.CONFIGURATION) {
- readData = restconfService.readConfigurationData(uriPath, uriInfo);
- } else {
- readData = restconfService.readOperationalData(uriPath, uriInfo);
- }
-
- final Optional<String> result = Optional.of(toJson(readData));
-
- LOG.debug("get returning: {}", result.get());
-
- return result;
- } catch (final Exception e) {
- if (!isDataMissing(e)) {
- propagateExceptionAs(uriPath, e, "GET");
- }
-
- LOG.debug("Data missing - returning absent");
- return Optional.empty();
- }
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- @SuppressFBWarnings(value = "NP_NULL_PARAM_DEREF", justification = "Unrecognised NullableDecl")
- @Override
- public Optional<String> invokeRpc(final String uriPath, final Optional<String> input)
- throws OperationFailedException {
- requireNonNull(uriPath, "uriPath can't be null");
-
- final String actualInput = input.isPresent() ? input.get() : null;
-
- LOG.debug("invokeRpc: uriPath: {}, input: {}", uriPath, actualInput);
-
- String output = null;
- try {
- NormalizedNodeContext outputContext;
- if (actualInput != null) {
- final InputStream entityStream = new ByteArrayInputStream(actualInput.getBytes(StandardCharsets.UTF_8));
- final NormalizedNodeContext inputContext =
- JsonNormalizedNodeBodyReader.readFrom(uriPath, entityStream, true, controllerContext);
-
- LOG.debug("Parsed YangInstanceIdentifier: {}", inputContext.getInstanceIdentifierContext()
- .getInstanceIdentifier());
- LOG.debug("Parsed NormalizedNode: {}", inputContext.getData());
-
- outputContext = restconfService.invokeRpc(uriPath, inputContext, null);
- } else {
- outputContext = restconfService.invokeRpc(uriPath, null, null);
- }
-
- if (outputContext.getData() != null) {
- output = toJson(outputContext);
- }
- } catch (final RuntimeException | IOException e) {
- propagateExceptionAs(uriPath, e, "RPC");
- }
-
- return Optional.ofNullable(output);
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- @Override
- public Optional<String> patch(final String uriPath, final String payload)
- throws OperationFailedException {
-
- String output = null;
- requireNonNull(payload, "payload can't be null");
-
- LOG.debug("patch: uriPath: {}, payload: {}", uriPath, payload);
-
- final InputStream entityStream = new ByteArrayInputStream(payload.getBytes(StandardCharsets.UTF_8));
-
- JsonToPatchBodyReader jsonToPatchBodyReader = new JsonToPatchBodyReader(controllerContext);
- final PatchContext context = jsonToPatchBodyReader.readFrom(uriPath, entityStream);
-
- LOG.debug("Parsed YangInstanceIdentifier: {}", context.getInstanceIdentifierContext().getInstanceIdentifier());
- LOG.debug("Parsed NormalizedNode: {}", context.getData());
-
- try {
- PatchStatusContext patchStatusContext = restconfService
- .patchConfigurationData(context, new SimpleUriInfo(uriPath));
- output = toJson(patchStatusContext);
- } catch (final Exception e) {
- propagateExceptionAs(uriPath, e, "PATCH");
- }
- return Optional.ofNullable(output);
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- @Override
- public Optional<String> subscribeToStream(final String identifier, final MultivaluedMap<String, String> params)
- throws OperationFailedException {
- //Note: We use http://127.0.0.1 because the Uri parser requires something there though it does nothing
- String uri = new StringBuilder("http://127.0.0.1:8081/restconf/streams/stream/").append(identifier).toString();
- MultivaluedMap queryParams = params != null ? params : new MultivaluedHashMap<String, String>();
- UriInfo uriInfo = new SimpleUriInfo(uri, queryParams);
-
- String jsonRes = null;
- try {
- NormalizedNodeContext res = restconfService.subscribeToStream(identifier, uriInfo);
- jsonRes = toJson(res);
- } catch (final Exception e) {
- propagateExceptionAs(identifier, e, "RPC");
- }
-
- return Optional.ofNullable(jsonRes);
- }
-
- private static String toJson(final PatchStatusContext patchStatusContext) throws IOException {
- final PatchJsonBodyWriter writer = new PatchJsonBodyWriter();
- final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- writer.writeTo(patchStatusContext, PatchStatusContext.class, null, EMPTY_ANNOTATIONS,
- MediaType.APPLICATION_JSON_TYPE, null, outputStream);
- return outputStream.toString(StandardCharsets.UTF_8);
- }
-
- private static String toJson(final NormalizedNodeContext readData) throws IOException {
- final NormalizedNodeJsonBodyWriter writer = new NormalizedNodeJsonBodyWriter();
- final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- writer.writeTo(readData, NormalizedNodeContext.class, null, EMPTY_ANNOTATIONS,
- MediaType.APPLICATION_JSON_TYPE, null, outputStream);
- return outputStream.toString(StandardCharsets.UTF_8);
- }
-
- private static boolean isDataMissing(final Exception exception) {
- boolean dataMissing = false;
- if (exception instanceof RestconfDocumentedException) {
- final RestconfDocumentedException rde = (RestconfDocumentedException)exception;
- if (!rde.getErrors().isEmpty()) {
- if (rde.getErrors().get(0).getErrorTag() == ErrorTag.DATA_MISSING) {
- dataMissing = true;
- }
- }
- }
-
- return dataMissing;
- }
-
- private static void propagateExceptionAs(final String uriPath, final Exception exception, final String operation)
- throws OperationFailedException {
- LOG.debug("Error for uriPath: {}", uriPath, exception);
-
- if (exception instanceof RestconfDocumentedException) {
- throw new OperationFailedException(String.format(
- "%s failed for URI %s", operation, uriPath), exception.getCause(),
- toRpcErrors(((RestconfDocumentedException)exception).getErrors()));
- }
-
- throw new OperationFailedException(String.format("%s failed for URI %s", operation, uriPath), exception);
- }
-
- private static RpcError[] toRpcErrors(final List<RestconfError> from) {
- final RpcError[] to = new RpcError[from.size()];
- int index = 0;
- for (final RestconfError e: from) {
- to[index++] = RpcResultBuilder.newError(e.getErrorType(), e.getErrorTag(), e.getErrorMessage());
- }
-
- return to;
- }
-}
+++ /dev/null
-/*
- * 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.sal.restconf.impl;
-
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.AnyxmlNode;
-import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MixinNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.SystemMapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UserMapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.CollectionNodeBuilder;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-
-class NormalizedDataPrunner {
-
- public DataContainerChild pruneDataAtDepth(final DataContainerChild node, final Integer depth) {
- if (depth == null) {
- return node;
- }
-
- if (node instanceof LeafNode || node instanceof LeafSetNode || node instanceof AnyxmlNode) {
- return node;
- } else if (node instanceof MixinNode) {
- return processMixinNode(node, depth);
- } else if (node instanceof DataContainerNode) {
- return processContainerNode(node, depth);
- }
- throw new IllegalStateException("Unexpected Mixin node occured why pruning data to requested depth");
- }
-
- private DataContainerChild processMixinNode(final NormalizedNode node, final Integer depth) {
- if (node instanceof AugmentationNode) {
- return processAugmentationNode(node, depth);
- } else if (node instanceof ChoiceNode) {
- return processChoiceNode(node, depth);
- } else if (node instanceof UserMapNode) {
- return processOrderedMapNode(node, depth);
- } else if (node instanceof MapNode) {
- return processMapNode(node, depth);
- } else if (node instanceof UnkeyedListNode) {
- return processUnkeyedListNode(node, depth);
- }
- throw new IllegalStateException("Unexpected Mixin node occured why pruning data to requested depth");
- }
-
- private DataContainerChild processContainerNode(final NormalizedNode node, final Integer depth) {
- final ContainerNode containerNode = (ContainerNode) node;
- DataContainerNodeBuilder<NodeIdentifier, ContainerNode> newContainerBuilder = Builders.containerBuilder()
- .withNodeIdentifier(containerNode.getIdentifier());
- if (depth > 1) {
- processDataContainerChild((DataContainerNode) node, depth, newContainerBuilder);
- }
- return newContainerBuilder.build();
- }
-
- private DataContainerChild processChoiceNode(final NormalizedNode node, final Integer depth) {
- final ChoiceNode choiceNode = (ChoiceNode) node;
- DataContainerNodeBuilder<NodeIdentifier, ChoiceNode> newChoiceBuilder = Builders.choiceBuilder()
- .withNodeIdentifier(choiceNode.getIdentifier());
-
- processDataContainerChild((DataContainerNode) node, depth, newChoiceBuilder);
-
- return newChoiceBuilder.build();
- }
-
- private DataContainerChild processAugmentationNode(final NormalizedNode node, final Integer depth) {
- final AugmentationNode augmentationNode = (AugmentationNode) node;
- DataContainerNodeBuilder<AugmentationIdentifier, ? extends DataContainerChild> newAugmentationBuilder =
- Builders.augmentationBuilder().withNodeIdentifier(augmentationNode.getIdentifier());
-
- processDataContainerChild((DataContainerNode) node, depth, newAugmentationBuilder);
-
- return newAugmentationBuilder.build();
- }
-
- private void processDataContainerChild(final DataContainerNode node, final Integer depth,
- final DataContainerNodeBuilder<?, ?> newBuilder) {
- for (DataContainerChild nodeValue : node.body()) {
- newBuilder.withChild(pruneDataAtDepth(nodeValue, depth - 1));
- }
- }
-
- private DataContainerChild processUnkeyedListNode(final NormalizedNode node, final Integer depth) {
- CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode> newUnkeyedListBuilder = Builders
- .unkeyedListBuilder();
- if (depth > 1) {
- for (UnkeyedListEntryNode oldUnkeyedListEntry : ((UnkeyedListNode) node).body()) {
- DataContainerNodeBuilder<NodeIdentifier, UnkeyedListEntryNode> newUnkeyedListEntry = Builders
- .unkeyedListEntryBuilder().withNodeIdentifier(oldUnkeyedListEntry.getIdentifier());
- for (DataContainerChild oldUnkeyedListEntryValue : oldUnkeyedListEntry.body()) {
- newUnkeyedListEntry.withChild(pruneDataAtDepth(oldUnkeyedListEntryValue, depth - 1));
- }
- newUnkeyedListBuilder.addChild(newUnkeyedListEntry.build());
- }
- }
- return newUnkeyedListBuilder.build();
- }
-
- private DataContainerChild processOrderedMapNode(final NormalizedNode node, final Integer depth) {
- CollectionNodeBuilder<MapEntryNode, UserMapNode> newOrderedMapNodeBuilder = Builders.orderedMapBuilder();
- processMapEntries(node, depth, newOrderedMapNodeBuilder);
- return newOrderedMapNodeBuilder.build();
- }
-
- private DataContainerChild processMapNode(final NormalizedNode node, final Integer depth) {
- CollectionNodeBuilder<MapEntryNode, SystemMapNode> newMapNodeBuilder = Builders.mapBuilder();
- processMapEntries(node, depth, newMapNodeBuilder);
- return newMapNodeBuilder.build();
- }
-
- private void processMapEntries(final NormalizedNode node, final Integer depth,
- final CollectionNodeBuilder<MapEntryNode, ? extends MapNode> newOrderedMapNodeBuilder) {
- if (depth > 1) {
- for (MapEntryNode oldMapEntryNode : ((MapNode) node).body()) {
- DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> newMapEntryNodeBuilder =
- Builders.mapEntryBuilder().withNodeIdentifier(oldMapEntryNode.getIdentifier());
- for (DataContainerChild mapEntryNodeValue : oldMapEntryNode.body()) {
- newMapEntryNodeBuilder.withChild(pruneDataAtDepth(mapEntryNodeValue, depth - 1));
- }
- newOrderedMapNodeBuilder.withChild(newMapEntryNodeBuilder.build());
- }
- }
- }
-}
+++ /dev/null
-/*
- * 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.sal.restconf.impl;
-
-import com.google.common.util.concurrent.FluentFuture;
-import javax.ws.rs.core.Response.Status;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-
-/**
- * Wrapper for status and future of PUT operation.
- */
-public class PutResult {
- private final Status status;
- private final FluentFuture<? extends CommitInfo> future;
-
- /**
- * Wrap status and future by constructor - make this immutable.
- *
- * @param status
- * status of operations
- * @param future
- * result of submit of PUT operation
- */
- public PutResult(final Status status, final FluentFuture<? extends CommitInfo> future) {
- this.status = status;
- this.future = future;
- }
-
- /**
- * Get status.
- *
- * @return {@link Status} result
- */
- public Status getStatus() {
- return this.status;
- }
-
- /**
- * Get future.
- *
- * @return {@link FluentFuture} result
- */
- public FluentFuture<? extends CommitInfo> getFutureOfPutData() {
- return this.future;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.sal.restconf.impl;
-
-import com.google.common.base.Strings;
-import javax.ws.rs.core.UriInfo;
-import org.opendaylight.netconf.sal.rest.impl.WriterParameters;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.errors.RestconfError;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.common.ErrorType;
-
-public final class QueryParametersParser {
-
- private enum UriParameters {
- PRETTY_PRINT("prettyPrint"),
- DEPTH("depth");
-
- private final String uriParameterName;
-
- UriParameters(final String uriParameterName) {
- this.uriParameterName = uriParameterName;
- }
-
- @Override
- public String toString() {
- return uriParameterName;
- }
- }
-
- private QueryParametersParser() {
-
- }
-
- public static WriterParameters parseWriterParameters(final UriInfo info) {
- final WriterParameters.WriterParametersBuilder wpBuilder = new WriterParameters.WriterParametersBuilder();
- if (info == null) {
- return wpBuilder.build();
- }
-
- String param = info.getQueryParameters(false).getFirst(UriParameters.DEPTH.toString());
- if (!Strings.isNullOrEmpty(param) && !"unbounded".equals(param)) {
- try {
- final int depth = Integer.parseInt(param);
- if (depth < 1) {
- throw new RestconfDocumentedException(
- new RestconfError(ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE,
- "Invalid depth parameter: " + depth, null,
- "The depth parameter must be an integer > 1 or \"unbounded\""));
- }
- wpBuilder.setDepth(depth);
- } catch (final NumberFormatException e) {
- throw new RestconfDocumentedException(e, new RestconfError(
- ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE,
- "Invalid depth parameter: " + e.getMessage(), null,
- "The depth parameter must be an integer > 1 or \"unbounded\""));
- }
- }
- param = info.getQueryParameters(false).getFirst(UriParameters.PRETTY_PRINT.toString());
- wpBuilder.setPrettyPrint("true".equals(param));
- return wpBuilder.build();
- }
-
-}
+++ /dev/null
-/*
- * 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.sal.restconf.impl;
-
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import org.opendaylight.mdsal.dom.api.DOMMountPoint;
-import org.opendaylight.netconf.sal.rest.impl.StringModuleInstanceIdentifierCodec;
-import org.opendaylight.restconf.common.util.IdentityValuesDTO;
-import org.opendaylight.restconf.common.util.IdentityValuesDTO.IdentityValue;
-import org.opendaylight.restconf.common.util.IdentityValuesDTO.Predicate;
-import org.opendaylight.restconf.common.util.RestUtil;
-import org.opendaylight.yangtools.concepts.IllegalArgumentCodec;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.XMLNamespace;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.codec.IdentityrefCodec;
-import org.opendaylight.yangtools.yang.data.api.codec.InstanceIdentifierCodec;
-import org.opendaylight.yangtools.yang.data.api.codec.LeafrefCodec;
-import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public final class RestCodec {
-
- private static final Logger LOG = LoggerFactory.getLogger(RestCodec.class);
-
- private RestCodec() {
- }
-
- // FIXME: IllegalArgumentCodec is not quite accurate
- public static IllegalArgumentCodec<Object, Object> from(final TypeDefinition<?> typeDefinition,
- final DOMMountPoint mountPoint, final ControllerContext controllerContext) {
- return new ObjectCodec(typeDefinition, mountPoint, controllerContext);
- }
-
- @SuppressWarnings("rawtypes")
- public static final class ObjectCodec implements IllegalArgumentCodec<Object, Object> {
-
- private static final Logger LOG = LoggerFactory.getLogger(ObjectCodec.class);
-
- public static final IllegalArgumentCodec LEAFREF_DEFAULT_CODEC = new LeafrefCodecImpl();
-
- private final ControllerContext controllerContext;
- private final IllegalArgumentCodec instanceIdentifier;
- private final IllegalArgumentCodec identityrefCodec;
-
- private final TypeDefinition<?> type;
-
- private ObjectCodec(final TypeDefinition<?> typeDefinition, final DOMMountPoint mountPoint,
- final ControllerContext controllerContext) {
- this.controllerContext = controllerContext;
- type = RestUtil.resolveBaseTypeFrom(typeDefinition);
- if (type instanceof IdentityrefTypeDefinition) {
- identityrefCodec = new IdentityrefCodecImpl(mountPoint, controllerContext);
- } else {
- identityrefCodec = null;
- }
- if (type instanceof InstanceIdentifierTypeDefinition) {
- instanceIdentifier = new InstanceIdentifierCodecImpl(mountPoint, controllerContext);
- } else {
- instanceIdentifier = null;
- }
- }
-
- @SuppressWarnings("unchecked")
- @Override
- @SuppressFBWarnings(value = "NP_NONNULL_RETURN_VIOLATION", justification = "Legacy code")
- public Object deserialize(final Object input) {
- try {
- if (type instanceof IdentityrefTypeDefinition) {
- if (input instanceof IdentityValuesDTO) {
- return identityrefCodec.deserialize(input);
- }
- if (LOG.isDebugEnabled()) {
- LOG.debug(
- "Value is not instance of IdentityrefTypeDefinition but is {}. "
- + "Therefore NULL is used as translation of - {}",
- input == null ? "null" : input.getClass(), String.valueOf(input));
- }
- // FIXME: this should be a hard error
- return null;
- } else if (type instanceof InstanceIdentifierTypeDefinition) {
- if (input instanceof IdentityValuesDTO) {
- return instanceIdentifier.deserialize(input);
- } else {
- final StringModuleInstanceIdentifierCodec codec = new StringModuleInstanceIdentifierCodec(
- controllerContext.getGlobalSchema());
- return codec.deserialize((String) input);
- }
- } else {
- final TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> typeAwarecodec =
- TypeDefinitionAwareCodec.from(type);
- if (typeAwarecodec != null) {
- if (input instanceof IdentityValuesDTO) {
- return typeAwarecodec.deserialize(((IdentityValuesDTO) input).getOriginValue());
- }
- return typeAwarecodec.deserialize(String.valueOf(input));
- } else {
- LOG.debug("Codec for type \"{}\" is not implemented yet.", type.getQName().getLocalName());
- // FIXME: this should be a hard error
- return null;
- }
- }
- } catch (final ClassCastException e) { // TODO remove this catch when everyone use codecs
- LOG.error("ClassCastException was thrown when codec is invoked with parameter {}", input, e);
- // FIXME: this should be a hard error
- return null;
- }
- }
-
- @SuppressWarnings("unchecked")
- @Override
- @SuppressFBWarnings(value = "NP_NONNULL_RETURN_VIOLATION", justification = "legacy code")
- public Object serialize(final Object input) {
- try {
- if (type instanceof IdentityrefTypeDefinition) {
- return identityrefCodec.serialize(input);
- } else if (type instanceof LeafrefTypeDefinition) {
- return LEAFREF_DEFAULT_CODEC.serialize(input);
- } else if (type instanceof InstanceIdentifierTypeDefinition) {
- return instanceIdentifier.serialize(input);
- } else {
- final TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> typeAwarecodec =
- TypeDefinitionAwareCodec.from(type);
- if (typeAwarecodec != null) {
- return typeAwarecodec.serialize(input);
- } else {
- LOG.debug("Codec for type \"{}\" is not implemented yet.", type.getQName().getLocalName());
- return null;
- }
- }
- } catch (final ClassCastException e) {
- // FIXME: remove this catch when everyone use codecs
- LOG.error("ClassCastException was thrown when codec is invoked with parameter {}", input, e);
- // FIXME: this should be a hard error
- return input;
- }
- }
-
- }
-
- public static class IdentityrefCodecImpl implements IdentityrefCodec<IdentityValuesDTO> {
- private static final Logger LOG = LoggerFactory.getLogger(IdentityrefCodecImpl.class);
-
- private final DOMMountPoint mountPoint;
- private final ControllerContext controllerContext;
-
- public IdentityrefCodecImpl(final DOMMountPoint mountPoint, final ControllerContext controllerContext) {
- this.mountPoint = mountPoint;
- this.controllerContext = controllerContext;
- }
-
- @Override
- public IdentityValuesDTO serialize(final QName data) {
- return new IdentityValuesDTO(data.getNamespace().toString(), data.getLocalName(), null, null);
- }
-
- @Override
- @SuppressFBWarnings(value = "NP_NONNULL_RETURN_VIOLATION", justification = "See FIXME below")
- public QName deserialize(final IdentityValuesDTO data) {
- final IdentityValue valueWithNamespace = data.getValuesWithNamespaces().get(0);
- final Module module = getModuleByNamespace(valueWithNamespace.getNamespace(), mountPoint,
- controllerContext);
- if (module == null) {
- // FIXME: this should be a hard error
- LOG.info("Module was not found for namespace {}", valueWithNamespace.getNamespace());
- LOG.info("Idenetityref will be translated as NULL for data - {}", String.valueOf(valueWithNamespace));
- return null;
- }
-
- return QName.create(module.getNamespace(), module.getRevision(), valueWithNamespace.getValue());
- }
- }
-
- public static class LeafrefCodecImpl implements LeafrefCodec<String> {
-
- @Override
- public String serialize(final Object data) {
- return String.valueOf(data);
- }
-
- @Override
- public Object deserialize(final String data) {
- return data;
- }
-
- }
-
- public static class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec<IdentityValuesDTO> {
- private static final Logger LOG = LoggerFactory.getLogger(InstanceIdentifierCodecImpl.class);
-
- private final DOMMountPoint mountPoint;
- private final ControllerContext controllerContext;
-
- public InstanceIdentifierCodecImpl(final DOMMountPoint mountPoint,
- final ControllerContext controllerContext) {
- this.mountPoint = mountPoint;
- this.controllerContext = controllerContext;
- }
-
- @Override
- public IdentityValuesDTO serialize(final YangInstanceIdentifier data) {
- final IdentityValuesDTO identityValuesDTO = new IdentityValuesDTO();
- for (final PathArgument pathArgument : data.getPathArguments()) {
- final IdentityValue identityValue = qNameToIdentityValue(pathArgument.getNodeType());
- if (pathArgument instanceof NodeIdentifierWithPredicates && identityValue != null) {
- final List<Predicate> predicates =
- keyValuesToPredicateList(((NodeIdentifierWithPredicates) pathArgument).entrySet());
- identityValue.setPredicates(predicates);
- } else if (pathArgument instanceof NodeWithValue && identityValue != null) {
- final List<Predicate> predicates = new ArrayList<>();
- final String value = String.valueOf(((NodeWithValue<?>) pathArgument).getValue());
- predicates.add(new Predicate(null, value));
- identityValue.setPredicates(predicates);
- }
- identityValuesDTO.add(identityValue);
- }
- return identityValuesDTO;
- }
-
- @SuppressFBWarnings(value = { "RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", "NP_NONNULL_RETURN_VIOLATION" },
- justification = "Unrecognised NullableDecl")
- @Override
- public YangInstanceIdentifier deserialize(final IdentityValuesDTO data) {
- final List<PathArgument> result = new ArrayList<>();
- final IdentityValue valueWithNamespace = data.getValuesWithNamespaces().get(0);
- final Module module = getModuleByNamespace(valueWithNamespace.getNamespace(), mountPoint,
- controllerContext);
- if (module == null) {
- LOG.info("Module by namespace '{}' of first node in instance-identifier was not found.",
- valueWithNamespace.getNamespace());
- LOG.info("Instance-identifier will be translated as NULL for data - {}",
- String.valueOf(valueWithNamespace.getValue()));
- // FIXME: this should be a hard error
- return null;
- }
-
- DataNodeContainer parentContainer = module;
- final List<IdentityValue> identities = data.getValuesWithNamespaces();
- for (int i = 0; i < identities.size(); i++) {
- final IdentityValue identityValue = identities.get(i);
- XMLNamespace validNamespace = resolveValidNamespace(identityValue.getNamespace(), mountPoint,
- controllerContext);
- final var found = ControllerContext.findInstanceDataChildByNameAndNamespace(
- parentContainer, identityValue.getValue(), validNamespace);
- if (found == null) {
- LOG.info("'{}' node was not found in {}", identityValue, parentContainer.getChildNodes());
- LOG.info("Instance-identifier will be translated as NULL for data - {}",
- String.valueOf(identityValue.getValue()));
- // FIXME: this should be a hard error
- return null;
- }
- final DataSchemaNode node = found.child;
- final QName qName = node.getQName();
- PathArgument pathArgument = null;
- if (identityValue.getPredicates().isEmpty()) {
- pathArgument = new NodeIdentifier(qName);
- } else {
- if (node instanceof LeafListSchemaNode) { // predicate is value of leaf-list entry
- final Predicate leafListPredicate = identityValue.getPredicates().get(0);
- if (!leafListPredicate.isLeafList()) {
- LOG.info("Predicate's data is not type of leaf-list. It should be in format \".='value'\"");
- LOG.info("Instance-identifier will be translated as NULL for data - {}",
- String.valueOf(identityValue.getValue()));
- // FIXME: this should be a hard error
- return null;
- }
- pathArgument = new NodeWithValue<>(qName, leafListPredicate.getValue());
- } else if (node instanceof ListSchemaNode) { // predicates are keys of list
- final DataNodeContainer listNode = (DataNodeContainer) node;
- final Map<QName, Object> predicatesMap = new HashMap<>();
- for (final Predicate predicate : identityValue.getPredicates()) {
- validNamespace = resolveValidNamespace(predicate.getName().getNamespace(), mountPoint,
- controllerContext);
- final var listKey = ControllerContext
- .findInstanceDataChildByNameAndNamespace(listNode, predicate.getName().getValue(),
- validNamespace);
- predicatesMap.put(listKey.child.getQName(), predicate.getValue());
- }
- pathArgument = NodeIdentifierWithPredicates.of(qName, predicatesMap);
- } else {
- LOG.info("Node {} is not List or Leaf-list.", node);
- LOG.info("Instance-identifier will be translated as NULL for data - {}",
- String.valueOf(identityValue.getValue()));
- // FIXME: this should be a hard error
- return null;
- }
- }
- result.add(pathArgument);
- if (i < identities.size() - 1) { // last element in instance-identifier can be other than
- // DataNodeContainer
- if (node instanceof DataNodeContainer) {
- parentContainer = (DataNodeContainer) node;
- } else {
- LOG.info("Node {} isn't instance of DataNodeContainer", node);
- LOG.info("Instance-identifier will be translated as NULL for data - {}",
- String.valueOf(identityValue.getValue()));
- // FIXME: this should be a hard error
- return null;
- }
- }
- }
-
- return result.isEmpty() ? null : YangInstanceIdentifier.create(result);
- }
-
- private static List<Predicate> keyValuesToPredicateList(final Set<Entry<QName, Object>> keyValues) {
- final List<Predicate> result = new ArrayList<>();
- for (final Entry<QName, Object> entry : keyValues) {
- final QName qualifiedName = entry.getKey();
- final Object value = entry.getValue();
- result.add(new Predicate(qNameToIdentityValue(qualifiedName), String.valueOf(value)));
- }
- return result;
- }
-
- private static IdentityValue qNameToIdentityValue(final QName qualifiedName) {
- if (qualifiedName != null) {
- return new IdentityValue(qualifiedName.getNamespace().toString(), qualifiedName.getLocalName());
- }
- return null;
- }
- }
-
- private static Module getModuleByNamespace(final String namespace, final DOMMountPoint mountPoint,
- final ControllerContext controllerContext) {
- final XMLNamespace validNamespace = resolveValidNamespace(namespace, mountPoint, controllerContext);
-
- Module module = null;
- if (mountPoint != null) {
- module = ControllerContext.findModuleByNamespace(mountPoint, validNamespace);
- } else {
- module = controllerContext.findModuleByNamespace(validNamespace);
- }
- if (module == null) {
- LOG.info("Module for namespace {} was not found.", validNamespace);
- return null;
- }
- return module;
- }
-
- private static XMLNamespace resolveValidNamespace(final String namespace, final DOMMountPoint mountPoint,
- final ControllerContext controllerContext) {
- XMLNamespace validNamespace;
- if (mountPoint != null) {
- validNamespace = ControllerContext.findNamespaceByModuleName(mountPoint, namespace);
- } else {
- validNamespace = controllerContext.findNamespaceByModuleName(namespace);
- }
- if (validNamespace == null) {
- validNamespace = XMLNamespace.of(namespace);
- }
-
- return validNamespace;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 - 2016 Brocade Communication Systems, Inc., 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.sal.restconf.impl;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Predicates;
-import com.google.common.base.Splitter;
-import com.google.common.base.Strings;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.util.concurrent.FluentFuture;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import java.net.URI;
-import java.time.Instant;
-import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatterBuilder;
-import java.time.format.DateTimeParseException;
-import java.time.temporal.ChronoField;
-import java.time.temporal.TemporalAccessor;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.ExecutionException;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.ResponseBuilder;
-import javax.ws.rs.core.Response.Status;
-import javax.ws.rs.core.UriBuilder;
-import javax.ws.rs.core.UriInfo;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.common.api.OptimisticLockFailedException;
-import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
-import org.opendaylight.mdsal.dom.api.DOMMountPoint;
-import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException;
-import org.opendaylight.mdsal.dom.api.DOMRpcResult;
-import org.opendaylight.mdsal.dom.api.DOMRpcService;
-import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
-import org.opendaylight.netconf.sal.rest.api.Draft02;
-import org.opendaylight.netconf.sal.rest.api.RestconfService;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext.FoundChild;
-import org.opendaylight.netconf.sal.streams.listeners.ListenerAdapter;
-import org.opendaylight.netconf.sal.streams.listeners.NotificationListenerAdapter;
-import org.opendaylight.netconf.sal.streams.listeners.Notificator;
-import org.opendaylight.netconf.sal.streams.websockets.WebSocketServer;
-import org.opendaylight.restconf.common.OperationsContent;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.patch.PatchContext;
-import org.opendaylight.restconf.common.patch.PatchStatusContext;
-import org.opendaylight.restconf.common.util.OperationsResourceUtils;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
-import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.CreateDataChangeEventSubscriptionInput1.Scope;
-import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping.NotificationOutputType;
-import org.opendaylight.yangtools.yang.common.Empty;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.common.ErrorType;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.QNameModule;
-import org.opendaylight.yangtools.yang.common.Revision;
-import org.opendaylight.yangtools.yang.common.XMLNamespace;
-import org.opendaylight.yangtools.yang.common.YangConstants;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.SystemLeafSetNode;
-import org.opendaylight.yangtools.yang.data.api.schema.SystemMapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.CollectionNodeBuilder;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.ListNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.data.impl.schema.SchemaAwareBuilders;
-import org.opendaylight.yangtools.yang.data.tree.api.ModifiedNodeDoesNotExistException;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Singleton
-public final class RestconfImpl implements RestconfService {
- /**
- * Notifications are served on port 8181.
- */
- private static final int NOTIFICATION_PORT = 8181;
-
- private static final int CHAR_NOT_FOUND = -1;
-
- private static final String SAL_REMOTE_NAMESPACE = "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote";
-
- private static final Logger LOG = LoggerFactory.getLogger(RestconfImpl.class);
-
- private static final LogicalDatastoreType DEFAULT_DATASTORE = LogicalDatastoreType.CONFIGURATION;
-
- private static final XMLNamespace NAMESPACE_EVENT_SUBSCRIPTION_AUGMENT =
- XMLNamespace.of("urn:sal:restconf:event:subscription");
-
- private static final String DATASTORE_PARAM_NAME = "datastore";
-
- private static final String SCOPE_PARAM_NAME = "scope";
-
- private static final String OUTPUT_TYPE_PARAM_NAME = "notification-output-type";
-
- private static final String NETCONF_BASE = "urn:ietf:params:xml:ns:netconf:base:1.0";
-
- private static final String NETCONF_BASE_PAYLOAD_NAME = "data";
-
- private static final QName NETCONF_BASE_QNAME = QName.create(QNameModule.create(XMLNamespace.of(NETCONF_BASE)),
- NETCONF_BASE_PAYLOAD_NAME).intern();
-
- private static final QNameModule SAL_REMOTE_AUGMENT = QNameModule.create(NAMESPACE_EVENT_SUBSCRIPTION_AUGMENT,
- Revision.of("2014-07-08"));
-
- private static final AugmentationIdentifier SAL_REMOTE_AUG_IDENTIFIER =
- new AugmentationIdentifier(ImmutableSet.of(
- QName.create(SAL_REMOTE_AUGMENT, "scope"), QName.create(SAL_REMOTE_AUGMENT, "datastore"),
- QName.create(SAL_REMOTE_AUGMENT, "notification-output-type")));
-
- public static final String DATA_SUBSCR = "data-change-event-subscription";
- private static final String CREATE_DATA_SUBSCR = "create-" + DATA_SUBSCR;
-
- public static final String NOTIFICATION_STREAM = "notification-stream";
- private static final String CREATE_NOTIFICATION_STREAM = "create-" + NOTIFICATION_STREAM;
-
- private static final DateTimeFormatter FORMATTER = new DateTimeFormatterBuilder()
- .appendValue(ChronoField.YEAR, 4).appendLiteral('-')
- .appendValue(ChronoField.MONTH_OF_YEAR, 2).appendLiteral('-')
- .appendValue(ChronoField.DAY_OF_MONTH, 2).appendLiteral('T')
- .appendValue(ChronoField.HOUR_OF_DAY, 2).appendLiteral(':')
- .appendValue(ChronoField.MINUTE_OF_HOUR, 2).appendLiteral(':')
- .appendValue(ChronoField.SECOND_OF_MINUTE, 2)
- .appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true)
- .appendOffset("+HH:MM", "Z").toFormatter();
-
- private final BrokerFacade broker;
-
- private final ControllerContext controllerContext;
-
- @Inject
- public RestconfImpl(final BrokerFacade broker, final ControllerContext controllerContext) {
- this.broker = broker;
- this.controllerContext = controllerContext;
- }
-
- /**
- * Factory method.
- *
- * @deprecated Just use {@link #RestconfImpl(BrokerFacade, ControllerContext)} constructor instead.
- */
- @Deprecated
- public static RestconfImpl newInstance(final BrokerFacade broker, final ControllerContext controllerContext) {
- return new RestconfImpl(broker, controllerContext);
- }
-
- @Override
- @Deprecated
- public NormalizedNodeContext getModules(final UriInfo uriInfo) {
- final Module restconfModule = getRestconfModule();
- final var stack = SchemaInferenceStack.of(controllerContext.getGlobalSchema());
- final var restconf = QName.create(restconfModule.getQNameModule(),
- Draft02.RestConfModule.RESTCONF_GROUPING_SCHEMA_NODE);
- stack.enterGrouping(restconf);
- stack.enterSchemaTree(restconf);
- final var modules = QName.create(restconf, Draft02.RestConfModule.MODULES_CONTAINER_SCHEMA_NODE);
- final var modulesSchemaNode = stack.enterSchemaTree(modules);
- checkState(modulesSchemaNode instanceof ContainerSchemaNode);
-
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> moduleContainerBuilder =
- SchemaAwareBuilders.containerBuilder((ContainerSchemaNode) modulesSchemaNode);
- moduleContainerBuilder.withChild(makeModuleMapNode(controllerContext.getAllModules()));
-
- return new NormalizedNodeContext(InstanceIdentifierContext.ofStack(stack, null),
- moduleContainerBuilder.build(), QueryParametersParser.parseWriterParameters(uriInfo));
- }
-
- /**
- * Valid only for mount point.
- */
- @Override
- @Deprecated
- public NormalizedNodeContext getModules(final String identifier, final UriInfo uriInfo) {
- if (!identifier.contains(ControllerContext.MOUNT)) {
- final String errMsg = "URI has bad format. If modules behind mount point should be showed,"
- + " URI has to end with " + ControllerContext.MOUNT;
- LOG.debug("{} for {}", errMsg, identifier);
- throw new RestconfDocumentedException(errMsg, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
-
- final InstanceIdentifierContext mountPointIdentifier =
- controllerContext.toMountPointIdentifier(identifier);
- final DOMMountPoint mountPoint = mountPointIdentifier.getMountPoint();
- final MapNode mountPointModulesMap = makeModuleMapNode(controllerContext.getAllModules(mountPoint));
-
- final Module restconfModule = getRestconfModule();
- final var stack = SchemaInferenceStack.of(controllerContext.getGlobalSchema());
- final var restconf = QName.create(restconfModule.getQNameModule(),
- Draft02.RestConfModule.RESTCONF_GROUPING_SCHEMA_NODE);
- stack.enterGrouping(restconf);
- stack.enterSchemaTree(restconf);
- final var modules = QName.create(restconf, Draft02.RestConfModule.MODULES_CONTAINER_SCHEMA_NODE);
- final var modulesSchemaNode = stack.enterSchemaTree(modules);
- checkState(modulesSchemaNode instanceof ContainerSchemaNode);
-
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> moduleContainerBuilder =
- SchemaAwareBuilders.containerBuilder((ContainerSchemaNode) modulesSchemaNode);
- moduleContainerBuilder.withChild(mountPointModulesMap);
-
- return new NormalizedNodeContext(InstanceIdentifierContext.ofStack(stack, null),
- moduleContainerBuilder.build(), QueryParametersParser.parseWriterParameters(uriInfo));
- }
-
- @Override
- @Deprecated
- public NormalizedNodeContext getModule(final String identifier, final UriInfo uriInfo) {
- final Entry<String, Revision> nameRev = getModuleNameAndRevision(requireNonNull(identifier));
- final Module module;
- final DOMMountPoint mountPoint;
- if (identifier.contains(ControllerContext.MOUNT)) {
- final InstanceIdentifierContext mountPointIdentifier =
- controllerContext.toMountPointIdentifier(identifier);
- mountPoint = mountPointIdentifier.getMountPoint();
- module = controllerContext.findModuleByNameAndRevision(mountPoint, nameRev.getKey(),
- nameRev.getValue());
- } else {
- mountPoint = null;
- module = controllerContext.findModuleByNameAndRevision(nameRev.getKey(), nameRev.getValue());
- }
-
- if (module == null) {
- LOG.debug("Module with name '{}' and revision '{}' was not found.", nameRev.getKey(), nameRev.getValue());
- throw new RestconfDocumentedException("Module with name '" + nameRev.getKey() + "' and revision '"
- + nameRev.getValue() + "' was not found.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
- }
-
- final Module restconfModule = getRestconfModule();
- final var stack = SchemaInferenceStack.of(controllerContext.getGlobalSchema());
- final var restconf = QName.create(restconfModule.getQNameModule(),
- Draft02.RestConfModule.RESTCONF_GROUPING_SCHEMA_NODE);
- stack.enterGrouping(restconf);
- stack.enterSchemaTree(restconf);
- stack.enterSchemaTree(QName.create(restconf, Draft02.RestConfModule.MODULES_CONTAINER_SCHEMA_NODE));
- stack.enterSchemaTree(QName.create(restconf, Draft02.RestConfModule.MODULE_LIST_SCHEMA_NODE));
-
- return new NormalizedNodeContext(InstanceIdentifierContext.ofStack(stack, mountPoint),
- makeModuleMapNode(Set.of(module)), QueryParametersParser.parseWriterParameters(uriInfo));
- }
-
- @Override
- @Deprecated
- public NormalizedNodeContext getAvailableStreams(final UriInfo uriInfo) {
- final Set<String> availableStreams = Notificator.getStreamNames();
- final Module restconfModule = getRestconfModule();
- final DataSchemaNode streamSchemaNode = controllerContext
- .getRestconfModuleRestConfSchemaNode(restconfModule, Draft02.RestConfModule.STREAM_LIST_SCHEMA_NODE);
- checkState(streamSchemaNode instanceof ListSchemaNode);
-
- final CollectionNodeBuilder<MapEntryNode, SystemMapNode> listStreamsBuilder =
- SchemaAwareBuilders.mapBuilder((ListSchemaNode) streamSchemaNode);
-
- for (final String streamName : availableStreams) {
- listStreamsBuilder.withChild(toStreamEntryNode(streamName, streamSchemaNode));
- }
-
- final var stack = SchemaInferenceStack.of(controllerContext.getGlobalSchema());
- final var restconf = QName.create(restconfModule.getQNameModule(),
- Draft02.RestConfModule.RESTCONF_GROUPING_SCHEMA_NODE);
- stack.enterGrouping(restconf);
- stack.enterSchemaTree(restconf);
- final var streams = QName.create(restconf, Draft02.RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE);
- final var streamsContainerSchemaNode = stack.enterSchemaTree(streams);
- checkState(streamsContainerSchemaNode instanceof ContainerSchemaNode);
-
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> streamsContainerBuilder =
- SchemaAwareBuilders.containerBuilder((ContainerSchemaNode) streamsContainerSchemaNode);
- streamsContainerBuilder.withChild(listStreamsBuilder.build());
-
- return new NormalizedNodeContext(InstanceIdentifierContext.ofStack(stack),
- streamsContainerBuilder.build(), QueryParametersParser.parseWriterParameters(uriInfo));
- }
-
- @Override
- @Deprecated
- public String getOperationsJSON() {
- return OperationsContent.JSON.bodyFor(controllerContext.getGlobalSchema());
- }
-
- @Override
- @Deprecated
- public String getOperationsXML() {
- return OperationsContent.XML.bodyFor(controllerContext.getGlobalSchema());
- }
-
- @Override
- @Deprecated
- public NormalizedNodeContext getOperations(final String identifier, final UriInfo uriInfo) {
- if (!identifier.contains(ControllerContext.MOUNT)) {
- final String errMsg = "URI has bad format. If operations behind mount point should be showed, URI has to "
- + " end with " + ControllerContext.MOUNT;
- LOG.debug("{} for {}", errMsg, identifier);
- throw new RestconfDocumentedException(errMsg, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
-
- final InstanceIdentifierContext mountPointIdentifier = controllerContext.toMountPointIdentifier(identifier);
- final DOMMountPoint mountPoint = mountPointIdentifier.getMountPoint();
- final var entry = OperationsResourceUtils.contextForModelContext(modelContext(mountPoint), mountPoint);
- return new NormalizedNodeContext(entry.getKey(), entry.getValue());
- }
-
- private Module getRestconfModule() {
- final Module restconfModule = controllerContext.getRestconfModule();
- if (restconfModule == null) {
- LOG.debug("ietf-restconf module was not found.");
- throw new RestconfDocumentedException("ietf-restconf module was not found.", ErrorType.APPLICATION,
- ErrorTag.OPERATION_NOT_SUPPORTED);
- }
-
- return restconfModule;
- }
-
- private static Entry<String, Revision> getModuleNameAndRevision(final String identifier) {
- final int mountIndex = identifier.indexOf(ControllerContext.MOUNT);
- String moduleNameAndRevision = "";
- if (mountIndex >= 0) {
- moduleNameAndRevision = identifier.substring(mountIndex + ControllerContext.MOUNT.length());
- } else {
- moduleNameAndRevision = identifier;
- }
-
- final Splitter splitter = Splitter.on('/').omitEmptyStrings();
- final List<String> pathArgs = splitter.splitToList(moduleNameAndRevision);
- if (pathArgs.size() < 2) {
- LOG.debug("URI has bad format. It should be \'moduleName/yyyy-MM-dd\' {}", identifier);
- throw new RestconfDocumentedException(
- "URI has bad format. End of URI should be in format \'moduleName/yyyy-MM-dd\'", ErrorType.PROTOCOL,
- ErrorTag.INVALID_VALUE);
- }
-
- try {
- return Map.entry(pathArgs.get(0), Revision.of(pathArgs.get(1)));
- } catch (final DateTimeParseException e) {
- LOG.debug("URI has bad format. It should be \'moduleName/yyyy-MM-dd\' {}", identifier);
- throw new RestconfDocumentedException("URI has bad format. It should be \'moduleName/yyyy-MM-dd\'",
- ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, e);
- }
- }
-
- @Override
- public Object getRoot() {
- return null;
- }
-
- @Override
- public NormalizedNodeContext invokeRpc(final String identifier, final NormalizedNodeContext payload,
- final UriInfo uriInfo) {
- if (payload == null) {
- // no payload specified, reroute this to no payload invokeRpc implementation
- return invokeRpc(identifier, uriInfo);
- }
-
- final SchemaNode schema = payload.getInstanceIdentifierContext().getSchemaNode();
- final ListenableFuture<? extends DOMRpcResult> response;
- final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint();
- final NormalizedNode input = nonnullInput(schema, payload.getData());
- final EffectiveModelContext schemaContext;
-
- if (mountPoint != null) {
- final Optional<DOMRpcService> mountRpcServices = mountPoint.getService(DOMRpcService.class);
- if (mountRpcServices.isEmpty()) {
- LOG.debug("Error: Rpc service is missing.");
- throw new RestconfDocumentedException("Rpc service is missing.");
- }
- schemaContext = modelContext(mountPoint);
- response = mountRpcServices.get().invokeRpc(schema.getQName(), input);
- } else {
- final XMLNamespace namespace = schema.getQName().getNamespace();
- if (namespace.toString().equals(SAL_REMOTE_NAMESPACE)) {
- if (identifier.contains(CREATE_DATA_SUBSCR)) {
- response = invokeSalRemoteRpcSubscribeRPC(payload);
- } else if (identifier.contains(CREATE_NOTIFICATION_STREAM)) {
- response = invokeSalRemoteRpcNotifiStrRPC(payload);
- } else {
- final String msg = "Not supported operation";
- LOG.warn(msg);
- throw new RestconfDocumentedException(msg, ErrorType.RPC, ErrorTag.OPERATION_NOT_SUPPORTED);
- }
- } else {
- response = broker.invokeRpc(schema.getQName(), input);
- }
- schemaContext = controllerContext.getGlobalSchema();
- }
-
- final DOMRpcResult result = checkRpcResponse(response);
-
- final NormalizedNode resultData;
- if (result != null && result.getResult() != null) {
- resultData = result.getResult();
- } else {
- resultData = null;
- }
-
- if (resultData != null && ((ContainerNode) resultData).isEmpty()) {
- throw new WebApplicationException(Response.Status.NO_CONTENT);
- }
-
- final var resultNodeSchema = (RpcDefinition) payload.getInstanceIdentifierContext().getSchemaNode();
- return new NormalizedNodeContext(
- InstanceIdentifierContext.ofRpcOutput(schemaContext, resultNodeSchema, mountPoint), resultData,
- QueryParametersParser.parseWriterParameters(uriInfo));
- }
-
- @SuppressFBWarnings(value = "NP_LOAD_OF_KNOWN_NULL_VALUE",
- justification = "Looks like a false positive, see below FIXME")
- private NormalizedNodeContext invokeRpc(final String identifier, final UriInfo uriInfo) {
- final DOMMountPoint mountPoint;
- final String identifierEncoded;
- final EffectiveModelContext schemaContext;
- if (identifier.contains(ControllerContext.MOUNT)) {
- // mounted RPC call - look up mount instance.
- final InstanceIdentifierContext mountPointId = controllerContext.toMountPointIdentifier(identifier);
- mountPoint = mountPointId.getMountPoint();
- schemaContext = modelContext(mountPoint);
- final int startOfRemoteRpcName =
- identifier.lastIndexOf(ControllerContext.MOUNT) + ControllerContext.MOUNT.length() + 1;
- final String remoteRpcName = identifier.substring(startOfRemoteRpcName);
- identifierEncoded = remoteRpcName;
-
- } else if (identifier.indexOf('/') == CHAR_NOT_FOUND) {
- identifierEncoded = identifier;
- mountPoint = null;
- schemaContext = controllerContext.getGlobalSchema();
- } else {
- LOG.debug("Identifier {} cannot contain slash character (/).", identifier);
- throw new RestconfDocumentedException(String.format("Identifier %n%s%ncan\'t contain slash character (/).%n"
- + "If slash is part of identifier name then use %%2F placeholder.", identifier), ErrorType.PROTOCOL,
- ErrorTag.INVALID_VALUE);
- }
-
- final String identifierDecoded = ControllerContext.urlPathArgDecode(identifierEncoded);
- final RpcDefinition rpc;
- if (mountPoint == null) {
- rpc = controllerContext.getRpcDefinition(identifierDecoded);
- } else {
- rpc = findRpc(modelContext(mountPoint), identifierDecoded);
- }
-
- if (rpc == null) {
- LOG.debug("RPC {} does not exist.", identifierDecoded);
- throw new RestconfDocumentedException("RPC does not exist.", ErrorType.RPC, ErrorTag.UNKNOWN_ELEMENT);
- }
-
- if (!rpc.getInput().getChildNodes().isEmpty()) {
- LOG.debug("No input specified for RPC {} with an input section", rpc);
- throw new RestconfDocumentedException("No input specified for RPC " + rpc
- + " with an input section defined", ErrorType.RPC, ErrorTag.MISSING_ELEMENT);
- }
-
- final ContainerNode input = defaultInput(rpc.getQName());
- final ListenableFuture<? extends DOMRpcResult> response;
- if (mountPoint != null) {
- final Optional<DOMRpcService> mountRpcServices = mountPoint.getService(DOMRpcService.class);
- if (mountRpcServices.isEmpty()) {
- throw new RestconfDocumentedException("Rpc service is missing.");
- }
- response = mountRpcServices.get().invokeRpc(rpc.getQName(), input);
- } else {
- response = broker.invokeRpc(rpc.getQName(), input);
- }
-
- final NormalizedNode result = checkRpcResponse(response).getResult();
- if (result != null && ((ContainerNode) result).isEmpty()) {
- throw new WebApplicationException(Response.Status.NO_CONTENT);
- }
-
- // FIXME: in reference to the above @SupressFBWarnings: "mountPoint" reference here trips up SpotBugs, as it
- // thinks it can only ever be null. Except it can very much be non-null. The core problem is the horrible
- // structure of this code where we have a sh*tload of checks for mountpoint above and all over the
- // codebase where all that difference should have been properly encapsulated.
- //
- // This is legacy code, so if anybody cares to do that refactor, feel free to contribute, but I am not
- // doing that work.
- final var iic = mountPoint == null ? InstanceIdentifierContext.ofLocalRpcOutput(schemaContext, rpc)
- : InstanceIdentifierContext.ofMountPointRpcOutput(mountPoint, schemaContext, rpc);
- return new NormalizedNodeContext(iic, result, QueryParametersParser.parseWriterParameters(uriInfo));
- }
-
- private static @NonNull NormalizedNode nonnullInput(final SchemaNode rpc, final NormalizedNode input) {
- return input != null ? input : defaultInput(rpc.getQName());
- }
-
- private static @NonNull ContainerNode defaultInput(final QName rpcName) {
- return ImmutableNodes.containerNode(YangConstants.operationInputQName(rpcName.getModule()));
- }
-
- @SuppressWarnings("checkstyle:avoidHidingCauseException")
- private static DOMRpcResult checkRpcResponse(final ListenableFuture<? extends DOMRpcResult> response) {
- if (response == null) {
- return null;
- }
- try {
- final DOMRpcResult retValue = response.get();
- if (retValue.getErrors().isEmpty()) {
- return retValue;
- }
- LOG.debug("RpcError message {}", retValue.getErrors());
- throw new RestconfDocumentedException("RpcError message", null, retValue.getErrors());
- } catch (final InterruptedException e) {
- final String errMsg = "The operation was interrupted while executing and did not complete.";
- LOG.debug("Rpc Interrupt - {}", errMsg, e);
- throw new RestconfDocumentedException(errMsg, ErrorType.RPC, ErrorTag.PARTIAL_OPERATION, e);
- } catch (final ExecutionException e) {
- LOG.debug("Execution RpcError: ", e);
- Throwable cause = e.getCause();
- if (cause == null) {
- throw new RestconfDocumentedException("The operation encountered an unexpected error while executing.",
- e);
- }
- while (cause.getCause() != null) {
- cause = cause.getCause();
- }
-
- if (cause instanceof IllegalArgumentException) {
- throw new RestconfDocumentedException(cause.getMessage(), ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- } else if (cause instanceof DOMRpcImplementationNotAvailableException) {
- throw new RestconfDocumentedException(cause.getMessage(), ErrorType.APPLICATION,
- ErrorTag.OPERATION_NOT_SUPPORTED);
- }
- throw new RestconfDocumentedException("The operation encountered an unexpected error while executing.",
- cause);
- } catch (final CancellationException e) {
- final String errMsg = "The operation was cancelled while executing.";
- LOG.debug("Cancel RpcExecution: {}", errMsg, e);
- throw new RestconfDocumentedException(errMsg, ErrorType.RPC, ErrorTag.PARTIAL_OPERATION);
- }
- }
-
- private static void validateInput(final SchemaNode inputSchema, final NormalizedNodeContext payload) {
- if (inputSchema != null && payload.getData() == null) {
- // expected a non null payload
- throw new RestconfDocumentedException("Input is required.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
- } else if (inputSchema == null && payload.getData() != null) {
- // did not expect any input
- throw new RestconfDocumentedException("No input expected.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
- }
- }
-
- private ListenableFuture<DOMRpcResult> invokeSalRemoteRpcSubscribeRPC(final NormalizedNodeContext payload) {
- final ContainerNode value = (ContainerNode) payload.getData();
- final QName rpcQName = payload.getInstanceIdentifierContext().getSchemaNode().getQName();
- final Optional<DataContainerChild> path =
- value.findChildByArg(new NodeIdentifier(QName.create(rpcQName, "path")));
- final Object pathValue = path.isPresent() ? path.get().body() : null;
-
- if (!(pathValue instanceof YangInstanceIdentifier)) {
- LOG.debug("Instance identifier {} was not normalized correctly", rpcQName);
- throw new RestconfDocumentedException("Instance identifier was not normalized correctly",
- ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED);
- }
-
- final YangInstanceIdentifier pathIdentifier = (YangInstanceIdentifier) pathValue;
- final String streamName;
- NotificationOutputType outputType = null;
- if (!pathIdentifier.isEmpty()) {
- final String fullRestconfIdentifier =
- DATA_SUBSCR + controllerContext.toFullRestconfIdentifier(pathIdentifier, null);
-
- LogicalDatastoreType datastore =
- parseEnumTypeParameter(value, LogicalDatastoreType.class, DATASTORE_PARAM_NAME);
- datastore = datastore == null ? DEFAULT_DATASTORE : datastore;
-
- Scope scope = parseEnumTypeParameter(value, Scope.class, SCOPE_PARAM_NAME);
- scope = scope == null ? Scope.BASE : scope;
-
- outputType = parseEnumTypeParameter(value, NotificationOutputType.class, OUTPUT_TYPE_PARAM_NAME);
- outputType = outputType == null ? NotificationOutputType.XML : outputType;
-
- streamName = Notificator
- .createStreamNameFromUri(fullRestconfIdentifier + "/datastore=" + datastore + "/scope=" + scope);
- } else {
- streamName = CREATE_DATA_SUBSCR;
- }
-
- if (Strings.isNullOrEmpty(streamName)) {
- LOG.debug("Path is empty or contains value node which is not Container or List built-in type at {}",
- pathIdentifier);
- throw new RestconfDocumentedException("Path is empty or contains value node which is not Container or List "
- + "built-in type.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
-
- if (!Notificator.existListenerFor(streamName)) {
- Notificator.createListener(pathIdentifier, streamName, outputType, controllerContext);
- }
-
- return Futures.immediateFuture(new DefaultDOMRpcResult(Builders.containerBuilder()
- .withNodeIdentifier(new NodeIdentifier(QName.create(rpcQName, "output")))
- .withChild(ImmutableNodes.leafNode(QName.create(rpcQName, "stream-name"), streamName))
- .build()));
- }
-
- private static RpcDefinition findRpc(final SchemaContext schemaContext, final String identifierDecoded) {
- final String[] splittedIdentifier = identifierDecoded.split(":");
- if (splittedIdentifier.length != 2) {
- LOG.debug("{} could not be split to 2 parts (module:rpc name)", identifierDecoded);
- throw new RestconfDocumentedException(identifierDecoded + " could not be split to 2 parts "
- + "(module:rpc name)", ErrorType.APPLICATION, ErrorTag.INVALID_VALUE);
- }
- for (final Module module : schemaContext.getModules()) {
- if (module.getName().equals(splittedIdentifier[0])) {
- for (final RpcDefinition rpcDefinition : module.getRpcs()) {
- if (rpcDefinition.getQName().getLocalName().equals(splittedIdentifier[1])) {
- return rpcDefinition;
- }
- }
- }
- }
- return null;
- }
-
- @Override
- public NormalizedNodeContext readConfigurationData(final String identifier, final UriInfo uriInfo) {
- boolean withDefaUsed = false;
- String withDefa = null;
-
- for (final Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
- switch (entry.getKey()) {
- case "with-defaults":
- if (!withDefaUsed) {
- withDefaUsed = true;
- withDefa = entry.getValue().iterator().next();
- } else {
- throw new RestconfDocumentedException("With-defaults parameter can be used only once.");
- }
- break;
- default:
- LOG.info("Unknown key : {}.", entry.getKey());
- break;
- }
- }
-
- // TODO: this flag is always ignored
- boolean tagged = false;
- if (withDefaUsed) {
- if ("report-all-tagged".equals(withDefa)) {
- tagged = true;
- withDefa = null;
- }
- if ("report-all".equals(withDefa)) {
- withDefa = null;
- }
- }
-
- final InstanceIdentifierContext iiWithData = controllerContext.toInstanceIdentifier(identifier);
- final DOMMountPoint mountPoint = iiWithData.getMountPoint();
- NormalizedNode data = null;
- final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier();
- if (mountPoint != null) {
- data = broker.readConfigurationData(mountPoint, normalizedII, withDefa);
- } else {
- data = broker.readConfigurationData(normalizedII, withDefa);
- }
- if (data == null) {
- throw dataMissing(identifier);
- }
- return new NormalizedNodeContext(iiWithData, data, QueryParametersParser.parseWriterParameters(uriInfo));
- }
-
- @Override
- public NormalizedNodeContext readOperationalData(final String identifier, final UriInfo uriInfo) {
- final InstanceIdentifierContext iiWithData = controllerContext.toInstanceIdentifier(identifier);
- final DOMMountPoint mountPoint = iiWithData.getMountPoint();
- NormalizedNode data = null;
- final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier();
- if (mountPoint != null) {
- data = broker.readOperationalData(mountPoint, normalizedII);
- } else {
- data = broker.readOperationalData(normalizedII);
- }
- if (data == null) {
- throw dataMissing(identifier);
- }
- return new NormalizedNodeContext(iiWithData, data, QueryParametersParser.parseWriterParameters(uriInfo));
- }
-
- private static RestconfDocumentedException dataMissing(final String identifier) {
- LOG.debug("Request could not be completed because the relevant data model content does not exist {}",
- identifier);
- return new RestconfDocumentedException("Request could not be completed because the relevant data model content "
- + "does not exist", ErrorType.APPLICATION, ErrorTag.DATA_MISSING);
- }
-
- @Override
- public Response updateConfigurationData(final String identifier, final NormalizedNodeContext payload,
- final UriInfo uriInfo) {
- boolean insertUsed = false;
- boolean pointUsed = false;
- String insert = null;
- String point = null;
-
- for (final Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
- switch (entry.getKey()) {
- case "insert":
- if (!insertUsed) {
- insertUsed = true;
- insert = entry.getValue().iterator().next();
- } else {
- throw new RestconfDocumentedException("Insert parameter can be used only once.");
- }
- break;
- case "point":
- if (!pointUsed) {
- pointUsed = true;
- point = entry.getValue().iterator().next();
- } else {
- throw new RestconfDocumentedException("Point parameter can be used only once.");
- }
- break;
- default:
- throw new RestconfDocumentedException("Bad parameter for post: " + entry.getKey());
- }
- }
-
- if (pointUsed && !insertUsed) {
- throw new RestconfDocumentedException("Point parameter can't be used without Insert parameter.");
- }
- if (pointUsed && (insert.equals("first") || insert.equals("last"))) {
- throw new RestconfDocumentedException(
- "Point parameter can be used only with 'after' or 'before' values of Insert parameter.");
- }
-
- requireNonNull(identifier);
-
- final InstanceIdentifierContext iiWithData = payload.getInstanceIdentifierContext();
-
- validateInput(iiWithData.getSchemaNode(), payload);
- validateTopLevelNodeName(payload, iiWithData.getInstanceIdentifier());
- validateListKeysEqualityInPayloadAndUri(payload);
-
- final DOMMountPoint mountPoint = iiWithData.getMountPoint();
- final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier();
-
- /*
- * There is a small window where another write transaction could be
- * updating the same data simultaneously and we get an
- * OptimisticLockFailedException. This error is likely transient and The
- * WriteTransaction#submit API docs state that a retry will likely
- * succeed. So we'll try again if that scenario occurs. If it fails a
- * third time then it probably will never succeed so we'll fail in that
- * case.
- *
- * By retrying we're attempting to hide the internal implementation of
- * the data store and how it handles concurrent updates from the
- * restconf client. The client has instructed us to put the data and we
- * should make every effort to do so without pushing optimistic lock
- * failures back to the client and forcing them to handle it via retry
- * (and having to document the behavior).
- */
- PutResult result = null;
- int tries = 2;
- while (true) {
- if (mountPoint != null) {
-
- result = broker.commitMountPointDataPut(mountPoint, normalizedII, payload.getData(), insert,
- point);
- } else {
- result = broker.commitConfigurationDataPut(controllerContext.getGlobalSchema(), normalizedII,
- payload.getData(), insert, point);
- }
-
- try {
- result.getFutureOfPutData().get();
- } catch (final InterruptedException e) {
- LOG.debug("Update failed for {}", identifier, e);
- throw new RestconfDocumentedException(e.getMessage(), e);
- } catch (final ExecutionException e) {
- final TransactionCommitFailedException failure = Throwables.getCauseAs(e,
- TransactionCommitFailedException.class);
- if (failure instanceof OptimisticLockFailedException) {
- if (--tries <= 0) {
- LOG.debug("Got OptimisticLockFailedException on last try - failing {}", identifier);
- throw new RestconfDocumentedException(e.getMessage(), e, failure.getErrorList());
- }
-
- LOG.debug("Got OptimisticLockFailedException - trying again {}", identifier);
- continue;
- }
-
- LOG.debug("Update failed for {}", identifier, e);
- throw RestconfDocumentedException.decodeAndThrow(e.getMessage(), failure);
- }
-
- return Response.status(result.getStatus()).build();
- }
- }
-
- private static void validateTopLevelNodeName(final NormalizedNodeContext node,
- final YangInstanceIdentifier identifier) {
-
- final String payloadName = node.getData().getIdentifier().getNodeType().getLocalName();
-
- // no arguments
- if (identifier.isEmpty()) {
- // no "data" payload
- if (!node.getData().getIdentifier().getNodeType().equals(NETCONF_BASE_QNAME)) {
- throw new RestconfDocumentedException("Instance identifier has to contain at least one path argument",
- ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
- }
- // any arguments
- } else {
- final String identifierName = identifier.getLastPathArgument().getNodeType().getLocalName();
- if (!payloadName.equals(identifierName)) {
- throw new RestconfDocumentedException(
- "Payload name (" + payloadName + ") is different from identifier name (" + identifierName + ")",
- ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
- }
- }
- }
-
- /**
- * Validates whether keys in {@code payload} are equal to values of keys in
- * {@code iiWithData} for list schema node.
- *
- * @throws RestconfDocumentedException
- * if key values or key count in payload and URI isn't equal
- *
- */
- private static void validateListKeysEqualityInPayloadAndUri(final NormalizedNodeContext payload) {
- checkArgument(payload != null);
- final InstanceIdentifierContext iiWithData = payload.getInstanceIdentifierContext();
- final PathArgument lastPathArgument = iiWithData.getInstanceIdentifier().getLastPathArgument();
- final SchemaNode schemaNode = iiWithData.getSchemaNode();
- final NormalizedNode data = payload.getData();
- if (schemaNode instanceof ListSchemaNode) {
- final List<QName> keyDefinitions = ((ListSchemaNode) schemaNode).getKeyDefinition();
- if (lastPathArgument instanceof NodeIdentifierWithPredicates && data instanceof MapEntryNode) {
- final Map<QName, Object> uriKeyValues = ((NodeIdentifierWithPredicates) lastPathArgument).asMap();
- isEqualUriAndPayloadKeyValues(uriKeyValues, (MapEntryNode) data, keyDefinitions);
- }
- }
- }
-
- @VisibleForTesting
- public static void isEqualUriAndPayloadKeyValues(final Map<QName, Object> uriKeyValues, final MapEntryNode payload,
- final List<QName> keyDefinitions) {
-
- final Map<QName, Object> mutableCopyUriKeyValues = new HashMap<>(uriKeyValues);
- for (final QName keyDefinition : keyDefinitions) {
- final Object uriKeyValue = RestconfDocumentedException.throwIfNull(
- // should be caught during parsing URI to InstanceIdentifier
- mutableCopyUriKeyValues.remove(keyDefinition), ErrorType.PROTOCOL, ErrorTag.DATA_MISSING,
- "Missing key %s in URI.", keyDefinition);
-
- final Object dataKeyValue = payload.getIdentifier().getValue(keyDefinition);
-
- if (!Objects.deepEquals(uriKeyValue, dataKeyValue)) {
- final String errMsg = "The value '" + uriKeyValue + "' for key '" + keyDefinition.getLocalName()
- + "' specified in the URI doesn't match the value '" + dataKeyValue
- + "' specified in the message body. ";
- throw new RestconfDocumentedException(errMsg, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
- }
- }
-
- @Override
- public Response createConfigurationData(final String identifier, final NormalizedNodeContext payload,
- final UriInfo uriInfo) {
- return createConfigurationData(payload, uriInfo);
- }
-
- @Override
- public Response createConfigurationData(final NormalizedNodeContext payload, final UriInfo uriInfo) {
- if (payload == null) {
- throw new RestconfDocumentedException("Input is required.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
- }
- final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint();
- final InstanceIdentifierContext iiWithData = payload.getInstanceIdentifierContext();
- final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier();
-
- boolean insertUsed = false;
- boolean pointUsed = false;
- String insert = null;
- String point = null;
-
- if (uriInfo != null) {
- for (final Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
- switch (entry.getKey()) {
- case "insert":
- if (!insertUsed) {
- insertUsed = true;
- insert = entry.getValue().iterator().next();
- } else {
- throw new RestconfDocumentedException("Insert parameter can be used only once.");
- }
- break;
- case "point":
- if (!pointUsed) {
- pointUsed = true;
- point = entry.getValue().iterator().next();
- } else {
- throw new RestconfDocumentedException("Point parameter can be used only once.");
- }
- break;
- default:
- throw new RestconfDocumentedException("Bad parameter for post: " + entry.getKey());
- }
- }
- }
-
- if (pointUsed && !insertUsed) {
- throw new RestconfDocumentedException("Point parameter can't be used without Insert parameter.");
- }
- if (pointUsed && (insert.equals("first") || insert.equals("last"))) {
- throw new RestconfDocumentedException(
- "Point parameter can be used only with 'after' or 'before' values of Insert parameter.");
- }
-
- FluentFuture<? extends CommitInfo> future;
- if (mountPoint != null) {
- future = broker.commitConfigurationDataPost(mountPoint, normalizedII, payload.getData(), insert,
- point);
- } else {
- future = broker.commitConfigurationDataPost(controllerContext.getGlobalSchema(), normalizedII,
- payload.getData(), insert, point);
- }
-
- try {
- future.get();
- } catch (final InterruptedException e) {
- LOG.info("Error creating data {}", uriInfo != null ? uriInfo.getPath() : "", e);
- throw new RestconfDocumentedException(e.getMessage(), e);
- } catch (final ExecutionException e) {
- LOG.info("Error creating data {}", uriInfo != null ? uriInfo.getPath() : "", e);
- throw RestconfDocumentedException.decodeAndThrow(e.getMessage(), Throwables.getCauseAs(e,
- TransactionCommitFailedException.class));
- }
-
- LOG.trace("Successfuly created data.");
-
- final ResponseBuilder responseBuilder = Response.status(Status.NO_CONTENT);
- // FIXME: Provide path to result.
- final URI location = resolveLocation(uriInfo, "", mountPoint, normalizedII);
- if (location != null) {
- responseBuilder.location(location);
- }
- return responseBuilder.build();
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- private URI resolveLocation(final UriInfo uriInfo, final String uriBehindBase, final DOMMountPoint mountPoint,
- final YangInstanceIdentifier normalizedII) {
- if (uriInfo == null) {
- // This is null if invoked internally
- return null;
- }
-
- final UriBuilder uriBuilder = uriInfo.getBaseUriBuilder();
- uriBuilder.path("config");
- try {
- uriBuilder.path(controllerContext.toFullRestconfIdentifier(normalizedII, mountPoint));
- } catch (final Exception e) {
- LOG.info("Location for instance identifier {} was not created", normalizedII, e);
- return null;
- }
- return uriBuilder.build();
- }
-
- @Override
- public Response deleteConfigurationData(final String identifier) {
- final InstanceIdentifierContext iiWithData = controllerContext.toInstanceIdentifier(identifier);
- final DOMMountPoint mountPoint = iiWithData.getMountPoint();
- final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier();
-
- final FluentFuture<? extends CommitInfo> future;
- if (mountPoint != null) {
- future = broker.commitConfigurationDataDelete(mountPoint, normalizedII);
- } else {
- future = broker.commitConfigurationDataDelete(normalizedII);
- }
-
- try {
- future.get();
- } catch (final InterruptedException e) {
- throw new RestconfDocumentedException(e.getMessage(), e);
- } catch (final ExecutionException e) {
- final Optional<Throwable> searchedException = Iterables.tryFind(Throwables.getCausalChain(e),
- Predicates.instanceOf(ModifiedNodeDoesNotExistException.class)).toJavaUtil();
- if (searchedException.isPresent()) {
- throw new RestconfDocumentedException("Data specified for delete doesn't exist.", ErrorType.APPLICATION,
- ErrorTag.DATA_MISSING, e);
- }
-
- throw RestconfDocumentedException.decodeAndThrow(e.getMessage(), Throwables.getCauseAs(e,
- TransactionCommitFailedException.class));
- }
-
- return Response.status(Status.OK).build();
- }
-
- /**
- * Subscribes to some path in schema context (stream) to listen on changes
- * on this stream.
- *
- * <p>
- * Additional parameters for subscribing to stream are loaded via rpc input
- * parameters:
- * <ul>
- * <li>datastore - default CONFIGURATION (other values of
- * {@link LogicalDatastoreType} enum type)</li>
- * <li>scope - default BASE (other values of {@link Scope})</li>
- * </ul>
- */
- @Override
- public NormalizedNodeContext subscribeToStream(final String identifier, final UriInfo uriInfo) {
- boolean startTimeUsed = false;
- boolean stopTimeUsed = false;
- Instant start = Instant.now();
- Instant stop = null;
- boolean filterUsed = false;
- String filter = null;
- boolean leafNodesOnlyUsed = false;
- boolean leafNodesOnly = false;
- boolean skipNotificationDataUsed = false;
- boolean skipNotificationData = false;
-
- for (final Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
- switch (entry.getKey()) {
- case "start-time":
- if (!startTimeUsed) {
- startTimeUsed = true;
- start = parseDateFromQueryParam(entry);
- } else {
- throw new RestconfDocumentedException("Start-time parameter can be used only once.");
- }
- break;
- case "stop-time":
- if (!stopTimeUsed) {
- stopTimeUsed = true;
- stop = parseDateFromQueryParam(entry);
- } else {
- throw new RestconfDocumentedException("Stop-time parameter can be used only once.");
- }
- break;
- case "filter":
- if (!filterUsed) {
- filterUsed = true;
- filter = entry.getValue().iterator().next();
- } else {
- throw new RestconfDocumentedException("Filter parameter can be used only once.");
- }
- break;
- case "odl-leaf-nodes-only":
- if (!leafNodesOnlyUsed) {
- leafNodesOnlyUsed = true;
- leafNodesOnly = Boolean.parseBoolean(entry.getValue().iterator().next());
- } else {
- throw new RestconfDocumentedException("Odl-leaf-nodes-only parameter can be used only once.");
- }
- break;
- case "odl-skip-notification-data":
- if (!skipNotificationDataUsed) {
- skipNotificationDataUsed = true;
- skipNotificationData = Boolean.parseBoolean(entry.getValue().iterator().next());
- } else {
- throw new RestconfDocumentedException(
- "Odl-skip-notification-data parameter can be used only once.");
- }
- break;
- default:
- throw new RestconfDocumentedException("Bad parameter used with notifications: " + entry.getKey());
- }
- }
- if (!startTimeUsed && stopTimeUsed) {
- throw new RestconfDocumentedException("Stop-time parameter has to be used with start-time parameter.");
- }
- URI response = null;
- if (identifier.contains(DATA_SUBSCR)) {
- response = dataSubs(identifier, uriInfo, start, stop, filter, leafNodesOnly, skipNotificationData);
- } else if (identifier.contains(NOTIFICATION_STREAM)) {
- response = notifStream(identifier, uriInfo, start, stop, filter);
- }
-
- if (response != null) {
- // prepare node with value of location
-
- final QName qnameBase = QName.create("subscribe:to:notification", "2016-10-28", "notifi");
- final QName locationQName = QName.create(qnameBase, "location");
-
- final var stack = SchemaInferenceStack.of(controllerContext.getGlobalSchema());
- stack.enterSchemaTree(qnameBase);
- stack.enterSchemaTree(locationQName);
-
- // prepare new header with location
- return new NormalizedNodeContext(InstanceIdentifierContext.ofStack(stack),
- ImmutableNodes.leafNode(locationQName, response.toString()), ImmutableMap.of("Location", response));
- }
-
- final String msg = "Bad type of notification of sal-remote";
- LOG.warn(msg);
- throw new RestconfDocumentedException(msg);
- }
-
- private static Instant parseDateFromQueryParam(final Entry<String, List<String>> entry) {
- final DateAndTime event = new DateAndTime(entry.getValue().iterator().next());
- final String value = event.getValue();
- final TemporalAccessor p;
- try {
- p = FORMATTER.parse(value);
- } catch (final DateTimeParseException e) {
- throw new RestconfDocumentedException("Cannot parse of value in date: " + value, e);
- }
- return Instant.from(p);
- }
-
- /**
- * Register notification listener by stream name.
- *
- * @param identifier
- * stream name
- * @param uriInfo
- * uriInfo
- * @param stop
- * stop-time of getting notification
- * @param start
- * start-time of getting notification
- * @param filter
- * indicate which subset of all possible events are of interest
- * @return {@link URI} of location
- */
- private URI notifStream(final String identifier, final UriInfo uriInfo, final Instant start,
- final Instant stop, final String filter) {
- final String streamName = Notificator.createStreamNameFromUri(identifier);
- if (Strings.isNullOrEmpty(streamName)) {
- throw new RestconfDocumentedException("Stream name is empty.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
- final List<NotificationListenerAdapter> listeners = Notificator.getNotificationListenerFor(streamName);
- if (listeners == null || listeners.isEmpty()) {
- throw new RestconfDocumentedException("Stream was not found.", ErrorType.PROTOCOL,
- ErrorTag.UNKNOWN_ELEMENT);
- }
-
- for (final NotificationListenerAdapter listener : listeners) {
- broker.registerToListenNotification(listener);
- listener.setQueryParams(start, Optional.ofNullable(stop), Optional.ofNullable(filter), false, false);
- }
-
- final UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder();
-
- final WebSocketServer webSocketServerInstance = WebSocketServer.getInstance(NOTIFICATION_PORT);
- final int notificationPort = webSocketServerInstance.getPort();
-
-
- final UriBuilder uriToWebsocketServerBuilder = uriBuilder.port(notificationPort).scheme(getWsScheme(uriInfo));
-
- return uriToWebsocketServerBuilder.replacePath(streamName).build();
- }
-
- private static String getWsScheme(final UriInfo uriInfo) {
- URI uri = uriInfo.getAbsolutePath();
- if (uri == null) {
- return "ws";
- }
- String subscriptionScheme = uri.getScheme().toLowerCase(Locale.ROOT);
- return subscriptionScheme.equals("https") ? "wss" : "ws";
- }
-
- /**
- * Register data change listener by stream name.
- *
- * @param identifier
- * stream name
- * @param uriInfo
- * uri info
- * @param stop
- * start-time of getting notification
- * @param start
- * stop-time of getting notification
- * @param filter
- * indicate which subset of all possible events are of interest
- * @return {@link URI} of location
- */
- private URI dataSubs(final String identifier, final UriInfo uriInfo, final Instant start, final Instant stop,
- final String filter, final boolean leafNodesOnly, final boolean skipNotificationData) {
- final String streamName = Notificator.createStreamNameFromUri(identifier);
- if (Strings.isNullOrEmpty(streamName)) {
- throw new RestconfDocumentedException("Stream name is empty.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
-
- final ListenerAdapter listener = Notificator.getListenerFor(streamName);
- if (listener == null) {
- throw new RestconfDocumentedException("Stream was not found.", ErrorType.PROTOCOL,
- ErrorTag.UNKNOWN_ELEMENT);
- }
- listener.setQueryParams(start, Optional.ofNullable(stop), Optional.ofNullable(filter), leafNodesOnly,
- skipNotificationData);
-
- final Map<String, String> paramToValues = resolveValuesFromUri(identifier);
- final LogicalDatastoreType datastore =
- parserURIEnumParameter(LogicalDatastoreType.class, paramToValues.get(DATASTORE_PARAM_NAME));
- if (datastore == null) {
- throw new RestconfDocumentedException("Stream name doesn't contains datastore value (pattern /datastore=)",
- ErrorType.APPLICATION, ErrorTag.MISSING_ATTRIBUTE);
- }
- final Scope scope = parserURIEnumParameter(Scope.class, paramToValues.get(SCOPE_PARAM_NAME));
- if (scope == null) {
- throw new RestconfDocumentedException("Stream name doesn't contains datastore value (pattern /scope=)",
- ErrorType.APPLICATION, ErrorTag.MISSING_ATTRIBUTE);
- }
-
- broker.registerToListenDataChanges(datastore, scope, listener);
-
- final UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder();
-
- final WebSocketServer webSocketServerInstance = WebSocketServer.getInstance(NOTIFICATION_PORT);
- final int notificationPort = webSocketServerInstance.getPort();
-
- final UriBuilder uriToWebsocketServerBuilder = uriBuilder.port(notificationPort).scheme(getWsScheme(uriInfo));
-
- return uriToWebsocketServerBuilder.replacePath(streamName).build();
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- @Override
- public PatchStatusContext patchConfigurationData(final String identifier, final PatchContext context,
- final UriInfo uriInfo) {
- if (context == null) {
- throw new RestconfDocumentedException("Input is required.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
- }
-
- try {
- return broker.patchConfigurationDataWithinTransaction(context);
- } catch (final Exception e) {
- LOG.debug("Patch transaction failed", e);
- throw new RestconfDocumentedException(e.getMessage(), e);
- }
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- @Override
- public PatchStatusContext patchConfigurationData(final PatchContext context, @Context final UriInfo uriInfo) {
- if (context == null) {
- throw new RestconfDocumentedException("Input is required.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
- }
-
- try {
- return broker.patchConfigurationDataWithinTransaction(context);
- } catch (final Exception e) {
- LOG.debug("Patch transaction failed", e);
- throw new RestconfDocumentedException(e.getMessage(), e);
- }
- }
-
- /**
- * Load parameter for subscribing to stream from input composite node.
- *
- * @param value
- * contains value
- * @return enum object if its string value is equal to {@code paramName}. In
- * other cases null.
- */
- private static <T> T parseEnumTypeParameter(final ContainerNode value, final Class<T> classDescriptor,
- final String paramName) {
- final Optional<DataContainerChild> optAugNode = value.findChildByArg(SAL_REMOTE_AUG_IDENTIFIER);
- if (optAugNode.isEmpty()) {
- return null;
- }
- final DataContainerChild augNode = optAugNode.get();
- if (!(augNode instanceof AugmentationNode)) {
- return null;
- }
- final Optional<DataContainerChild> enumNode = ((AugmentationNode) augNode).findChildByArg(
- new NodeIdentifier(QName.create(SAL_REMOTE_AUGMENT, paramName)));
- if (enumNode.isEmpty()) {
- return null;
- }
- final Object rawValue = enumNode.get().body();
- if (!(rawValue instanceof String)) {
- return null;
- }
-
- return resolveAsEnum(classDescriptor, (String) rawValue);
- }
-
- /**
- * Checks whether {@code value} is one of the string representation of
- * enumeration {@code classDescriptor}.
- *
- * @return enum object if string value of {@code classDescriptor}
- * enumeration is equal to {@code value}. Other cases null.
- */
- private static <T> T parserURIEnumParameter(final Class<T> classDescriptor, final String value) {
- if (Strings.isNullOrEmpty(value)) {
- return null;
- }
- return resolveAsEnum(classDescriptor, value);
- }
-
- private static <T> T resolveAsEnum(final Class<T> classDescriptor, final String value) {
- final T[] enumConstants = classDescriptor.getEnumConstants();
- if (enumConstants != null) {
- for (final T enm : classDescriptor.getEnumConstants()) {
- if (((Enum<?>) enm).name().equals(value)) {
- return enm;
- }
- }
- }
- return null;
- }
-
- private static Map<String, String> resolveValuesFromUri(final String uri) {
- final Map<String, String> result = new HashMap<>();
- final String[] tokens = uri.split("/");
- for (int i = 1; i < tokens.length; i++) {
- final String[] parameterTokens = tokens[i].split("=");
- if (parameterTokens.length == 2) {
- result.put(parameterTokens[0], parameterTokens[1]);
- }
- }
- return result;
- }
-
- private MapNode makeModuleMapNode(final Collection<? extends Module> modules) {
- requireNonNull(modules);
- final Module restconfModule = getRestconfModule();
- final DataSchemaNode moduleSchemaNode = controllerContext
- .getRestconfModuleRestConfSchemaNode(restconfModule, Draft02.RestConfModule.MODULE_LIST_SCHEMA_NODE);
- checkState(moduleSchemaNode instanceof ListSchemaNode);
-
- final CollectionNodeBuilder<MapEntryNode, SystemMapNode> listModuleBuilder =
- SchemaAwareBuilders.mapBuilder((ListSchemaNode) moduleSchemaNode);
-
- for (final Module module : modules) {
- listModuleBuilder.withChild(toModuleEntryNode(module, moduleSchemaNode));
- }
- return listModuleBuilder.build();
- }
-
- private static MapEntryNode toModuleEntryNode(final Module module, final DataSchemaNode moduleSchemaNode) {
- checkArgument(moduleSchemaNode instanceof ListSchemaNode,
- "moduleSchemaNode has to be of type ListSchemaNode");
- final ListSchemaNode listModuleSchemaNode = (ListSchemaNode) moduleSchemaNode;
- final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> moduleNodeValues =
- SchemaAwareBuilders.mapEntryBuilder(listModuleSchemaNode);
-
- var instanceDataChildrenByName =
- ControllerContext.findInstanceDataChildrenByName(listModuleSchemaNode, "name");
- final LeafSchemaNode nameSchemaNode = getFirstLeaf(instanceDataChildrenByName);
- moduleNodeValues.withChild(
- SchemaAwareBuilders.leafBuilder(nameSchemaNode).withValue(module.getName()).build());
-
- final QNameModule qNameModule = module.getQNameModule();
-
- instanceDataChildrenByName =
- ControllerContext.findInstanceDataChildrenByName(listModuleSchemaNode, "revision");
- final LeafSchemaNode revisionSchemaNode = getFirstLeaf(instanceDataChildrenByName);
- final Optional<Revision> revision = qNameModule.getRevision();
- moduleNodeValues.withChild(SchemaAwareBuilders.leafBuilder(revisionSchemaNode)
- .withValue(revision.map(Revision::toString).orElse("")).build());
-
- instanceDataChildrenByName =
- ControllerContext.findInstanceDataChildrenByName(listModuleSchemaNode, "namespace");
- final LeafSchemaNode namespaceSchemaNode = getFirstLeaf(instanceDataChildrenByName);
- moduleNodeValues.withChild(SchemaAwareBuilders.leafBuilder(namespaceSchemaNode)
- .withValue(qNameModule.getNamespace().toString()).build());
-
- instanceDataChildrenByName =
- ControllerContext.findInstanceDataChildrenByName(listModuleSchemaNode, "feature");
- final LeafListSchemaNode featureSchemaNode = getFirst(instanceDataChildrenByName, LeafListSchemaNode.class);
- final ListNodeBuilder<Object, SystemLeafSetNode<Object>> featuresBuilder =
- SchemaAwareBuilders.leafSetBuilder(featureSchemaNode);
- for (final FeatureDefinition feature : module.getFeatures()) {
- featuresBuilder.withChild(SchemaAwareBuilders.leafSetEntryBuilder(featureSchemaNode)
- .withValue(feature.getQName().getLocalName()).build());
- }
- moduleNodeValues.withChild(featuresBuilder.build());
-
- return moduleNodeValues.build();
- }
-
- protected MapEntryNode toStreamEntryNode(final String streamName, final DataSchemaNode streamSchemaNode) {
- checkArgument(streamSchemaNode instanceof ListSchemaNode,
- "streamSchemaNode has to be of type ListSchemaNode");
- final ListSchemaNode listStreamSchemaNode = (ListSchemaNode) streamSchemaNode;
- final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> streamNodeValues =
- SchemaAwareBuilders.mapEntryBuilder(listStreamSchemaNode);
-
- var instanceDataChildrenByName =
- ControllerContext.findInstanceDataChildrenByName(listStreamSchemaNode, "name");
- final LeafSchemaNode nameSchemaNode = getFirstLeaf(instanceDataChildrenByName);
- streamNodeValues.withChild(
- SchemaAwareBuilders.leafBuilder(nameSchemaNode).withValue(streamName).build());
-
- instanceDataChildrenByName =
- ControllerContext.findInstanceDataChildrenByName(listStreamSchemaNode, "description");
- final LeafSchemaNode descriptionSchemaNode = getFirstLeaf(instanceDataChildrenByName);
- streamNodeValues.withChild(SchemaAwareBuilders.leafBuilder(descriptionSchemaNode)
- .withValue("DESCRIPTION_PLACEHOLDER")
- .build());
-
- instanceDataChildrenByName =
- ControllerContext.findInstanceDataChildrenByName(listStreamSchemaNode, "replay-support");
- final LeafSchemaNode replaySupportSchemaNode = getFirstLeaf(instanceDataChildrenByName);
- streamNodeValues.withChild(SchemaAwareBuilders.leafBuilder(replaySupportSchemaNode)
- .withValue(Boolean.TRUE).build());
-
- instanceDataChildrenByName =
- ControllerContext.findInstanceDataChildrenByName(listStreamSchemaNode, "replay-log-creation-time");
- final LeafSchemaNode replayLogCreationTimeSchemaNode = getFirstLeaf(instanceDataChildrenByName);
- streamNodeValues.withChild(
- SchemaAwareBuilders.leafBuilder(replayLogCreationTimeSchemaNode).withValue("").build());
-
- instanceDataChildrenByName = ControllerContext.findInstanceDataChildrenByName(listStreamSchemaNode, "events");
- final LeafSchemaNode eventsSchemaNode = getFirstLeaf(instanceDataChildrenByName);
- streamNodeValues.withChild(
- SchemaAwareBuilders.leafBuilder(eventsSchemaNode).withValue(Empty.value()).build());
-
- return streamNodeValues.build();
- }
-
- /**
- * Prepare stream for notification.
- *
- * @param payload
- * contains list of qnames of notifications
- * @return - checked future object
- */
- private ListenableFuture<DOMRpcResult> invokeSalRemoteRpcNotifiStrRPC(final NormalizedNodeContext payload) {
- final ContainerNode data = (ContainerNode) payload.getData();
- LeafSetNode leafSet = null;
- String outputType = "XML";
- for (final DataContainerChild dataChild : data.body()) {
- if (dataChild instanceof LeafSetNode) {
- leafSet = (LeafSetNode) dataChild;
- } else if (dataChild instanceof AugmentationNode) {
- outputType = (String) ((AugmentationNode) dataChild).body().iterator().next().body();
- }
- }
-
- final Collection<LeafSetEntryNode<?>> entryNodes = leafSet.body();
- final List<Absolute> paths = new ArrayList<>();
-
- StringBuilder streamNameBuilder = new StringBuilder(CREATE_NOTIFICATION_STREAM).append('/');
- final Iterator<LeafSetEntryNode<?>> iterator = entryNodes.iterator();
- while (iterator.hasNext()) {
- final QName valueQName = QName.create((String) iterator.next().body());
- final XMLNamespace namespace = valueQName.getModule().getNamespace();
- final Module module = controllerContext.findModuleByNamespace(namespace);
- checkNotNull(module, "Module for namespace %s does not exist", namespace);
- NotificationDefinition notifiDef = null;
- for (final NotificationDefinition notification : module.getNotifications()) {
- if (notification.getQName().equals(valueQName)) {
- notifiDef = notification;
- break;
- }
- }
- final String moduleName = module.getName();
- if (notifiDef == null) {
- throw new IllegalArgumentException("Notification " + valueQName + " does not exist in module "
- + moduleName);
- }
-
- paths.add(Absolute.of(notifiDef.getQName()));
- streamNameBuilder.append(moduleName).append(':').append(valueQName.getLocalName());
- if (iterator.hasNext()) {
- streamNameBuilder.append(',');
- }
- }
-
- final String streamName = streamNameBuilder.toString();
- final QName rpcQName = payload.getInstanceIdentifierContext().getSchemaNode().getQName();
-
- if (!Notificator.existNotificationListenerFor(streamName)) {
- Notificator.createNotificationListener(paths, streamName, outputType, controllerContext);
- }
-
- return Futures.immediateFuture(new DefaultDOMRpcResult(Builders.containerBuilder()
- .withNodeIdentifier(new NodeIdentifier(QName.create(rpcQName, "output")))
- .withChild(ImmutableNodes.leafNode(QName.create(rpcQName, "notification-stream-identifier"), streamName))
- .build()));
- }
-
- private static LeafSchemaNode getFirstLeaf(final List<FoundChild> children) {
- return getFirst(children, LeafSchemaNode.class);
- }
-
- private static <T extends DataSchemaNode> T getFirst(final List<FoundChild> children, final Class<T> expected) {
- checkState(!children.isEmpty());
- final var first = children.get(0);
- checkState(expected.isInstance(first.child));
- return expected.cast(first.child);
- }
-
- private static EffectiveModelContext modelContext(final DOMMountPoint mountPoint) {
- return mountPoint.getService(DOMSchemaService.class)
- .flatMap(svc -> Optional.ofNullable(svc.getGlobalContext()))
- .orElse(null);
- }
-}
+++ /dev/null
-/*
- * 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.sal.restconf.impl;
-
-import static java.util.Objects.requireNonNull;
-
-import java.math.BigInteger;
-import org.opendaylight.controller.md.sal.common.util.jmx.AbstractMXBean;
-import org.opendaylight.netconf.sal.rest.api.RestConnector;
-import org.opendaylight.netconf.sal.restconf.impl.jmx.Config;
-import org.opendaylight.netconf.sal.restconf.impl.jmx.Delete;
-import org.opendaylight.netconf.sal.restconf.impl.jmx.Get;
-import org.opendaylight.netconf.sal.restconf.impl.jmx.Operational;
-import org.opendaylight.netconf.sal.restconf.impl.jmx.Post;
-import org.opendaylight.netconf.sal.restconf.impl.jmx.Put;
-import org.opendaylight.netconf.sal.restconf.impl.jmx.RestConnectorRuntimeMXBean;
-import org.opendaylight.netconf.sal.restconf.impl.jmx.Rpcs;
-import org.opendaylight.netconf.sal.streams.websockets.WebSocketServer;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
-
-public class RestconfProviderImpl extends AbstractMXBean
- implements AutoCloseable, RestConnector, RestConnectorRuntimeMXBean {
- private final IpAddress websocketAddress;
- private final PortNumber websocketPort;
- private final StatisticsRestconfServiceWrapper stats;
- private Thread webSocketServerThread;
-
- public RestconfProviderImpl(final StatisticsRestconfServiceWrapper stats, final IpAddress websocketAddress,
- final PortNumber websocketPort) {
- super("Draft02ProviderStatistics", "restconf-connector", null);
- this.stats = requireNonNull(stats);
- this.websocketAddress = requireNonNull(websocketAddress);
- this.websocketPort = requireNonNull(websocketPort);
- }
-
- public void start() {
- this.webSocketServerThread = new Thread(WebSocketServer.createInstance(
- websocketAddress.stringValue(), websocketPort.getValue().toJava()));
- this.webSocketServerThread.setName("Web socket server on port " + websocketPort);
- this.webSocketServerThread.start();
-
- registerMBean();
- }
-
- @Override
- public void close() {
- WebSocketServer.destroyInstance();
- if (this.webSocketServerThread != null) {
- this.webSocketServerThread.interrupt();
- }
-
- unregisterMBean();
- }
-
- @Override
- public Config getConfig() {
- final Config config = new Config();
-
- final Get get = new Get();
- get.setReceivedRequests(this.stats.getConfigGet());
- get.setSuccessfulResponses(this.stats.getSuccessGetConfig());
- get.setFailedResponses(this.stats.getFailureGetConfig());
- config.setGet(get);
-
- final Post post = new Post();
- post.setReceivedRequests(this.stats.getConfigPost());
- post.setSuccessfulResponses(this.stats.getSuccessPost());
- post.setFailedResponses(this.stats.getFailurePost());
- config.setPost(post);
-
- final Put put = new Put();
- put.setReceivedRequests(this.stats.getConfigPut());
- put.setSuccessfulResponses(this.stats.getSuccessPut());
- put.setFailedResponses(this.stats.getFailurePut());
- config.setPut(put);
-
- final Delete delete = new Delete();
- delete.setReceivedRequests(this.stats.getConfigDelete());
- delete.setSuccessfulResponses(this.stats.getSuccessDelete());
- delete.setFailedResponses(this.stats.getFailureDelete());
- config.setDelete(delete);
-
- return config;
- }
-
- @Override
- public Operational getOperational() {
- final BigInteger opGet = this.stats.getOperationalGet();
- final Operational operational = new Operational();
- final Get get = new Get();
- get.setReceivedRequests(opGet);
- get.setSuccessfulResponses(this.stats.getSuccessGetOperational());
- get.setFailedResponses(this.stats.getFailureGetOperational());
- operational.setGet(get);
- return operational;
- }
-
- @Override
- public Rpcs getRpcs() {
- final BigInteger rpcInvoke = this.stats.getRpc();
- final Rpcs rpcs = new Rpcs();
- rpcs.setReceivedRequests(rpcInvoke);
- return rpcs;
- }
-}
+++ /dev/null
-/*
- * 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.sal.restconf.impl;
-
-import java.math.BigInteger;
-import java.util.concurrent.atomic.AtomicLong;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
-import javax.ws.rs.core.UriInfo;
-import org.opendaylight.netconf.sal.rest.api.RestconfService;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.restconf.common.patch.PatchContext;
-import org.opendaylight.restconf.common.patch.PatchStatusContext;
-
-@Singleton
-public final class StatisticsRestconfServiceWrapper implements RestconfService {
-
- AtomicLong operationalGet = new AtomicLong();
- AtomicLong configGet = new AtomicLong();
- AtomicLong rpc = new AtomicLong();
- AtomicLong configPost = new AtomicLong();
- AtomicLong configPut = new AtomicLong();
- AtomicLong configDelete = new AtomicLong();
- AtomicLong successGetConfig = new AtomicLong();
- AtomicLong successGetOperational = new AtomicLong();
- AtomicLong successPost = new AtomicLong();
- AtomicLong successPut = new AtomicLong();
- AtomicLong successDelete = new AtomicLong();
- AtomicLong failureGetConfig = new AtomicLong();
- AtomicLong failureGetOperational = new AtomicLong();
- AtomicLong failurePost = new AtomicLong();
- AtomicLong failurePut = new AtomicLong();
- AtomicLong failureDelete = new AtomicLong();
-
- private final RestconfService delegate;
-
- @Inject
- public StatisticsRestconfServiceWrapper(final RestconfImpl delegate) {
- this.delegate = delegate;
- }
-
- /**
- * Factory method.
- *
- * @deprecated Just use {@link #StatisticsRestconfServiceWrapper(RestconfImpl)} constructor instead.
- */
- @Deprecated
- public static StatisticsRestconfServiceWrapper newInstance(RestconfImpl delegate) {
- return new StatisticsRestconfServiceWrapper(delegate);
- }
-
- @Override
- public Object getRoot() {
- return this.delegate.getRoot();
- }
-
- @Override
- public NormalizedNodeContext getModules(final UriInfo uriInfo) {
- return this.delegate.getModules(uriInfo);
- }
-
- @Override
- public NormalizedNodeContext getModules(final String identifier, final UriInfo uriInfo) {
- return this.delegate.getModules(identifier, uriInfo);
- }
-
- @Override
- public NormalizedNodeContext getModule(final String identifier, final UriInfo uriInfo) {
- return this.delegate.getModule(identifier, uriInfo);
- }
-
- @Override
- public String getOperationsJSON() {
- return this.delegate.getOperationsJSON();
- }
-
- @Override
- public String getOperationsXML() {
- return this.delegate.getOperationsXML();
- }
-
- @Override
- public NormalizedNodeContext getOperations(final String identifier, final UriInfo uriInfo) {
- return this.delegate.getOperations(identifier, uriInfo);
- }
-
- @Override
- public NormalizedNodeContext invokeRpc(final String identifier, final NormalizedNodeContext payload,
- final UriInfo uriInfo) {
- this.rpc.incrementAndGet();
- return this.delegate.invokeRpc(identifier, payload, uriInfo);
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- @Override
- public NormalizedNodeContext readConfigurationData(final String identifier, final UriInfo uriInfo) {
- this.configGet.incrementAndGet();
- NormalizedNodeContext normalizedNodeContext = null;
- try {
- normalizedNodeContext = this.delegate.readConfigurationData(identifier, uriInfo);
- if (normalizedNodeContext.getData() != null) {
- this.successGetConfig.incrementAndGet();
- } else {
- this.failureGetConfig.incrementAndGet();
- }
- } catch (final Exception e) {
- this.failureGetConfig.incrementAndGet();
- throw e;
- }
- return normalizedNodeContext;
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- @Override
- public NormalizedNodeContext readOperationalData(final String identifier, final UriInfo uriInfo) {
- this.operationalGet.incrementAndGet();
- NormalizedNodeContext normalizedNodeContext = null;
- try {
- normalizedNodeContext = this.delegate.readOperationalData(identifier, uriInfo);
- if (normalizedNodeContext.getData() != null) {
- this.successGetOperational.incrementAndGet();
- } else {
- this.failureGetOperational.incrementAndGet();
- }
- } catch (final Exception e) {
- this.failureGetOperational.incrementAndGet();
- throw e;
- }
- return normalizedNodeContext;
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- @Override
- public Response updateConfigurationData(final String identifier, final NormalizedNodeContext payload,
- final UriInfo uriInfo) {
- this.configPut.incrementAndGet();
- Response response = null;
- try {
- response = this.delegate.updateConfigurationData(identifier, payload, uriInfo);
- if (response.getStatus() == Status.OK.getStatusCode()) {
- this.successPut.incrementAndGet();
- } else {
- this.failurePut.incrementAndGet();
- }
- } catch (final Exception e) {
- this.failurePut.incrementAndGet();
- throw e;
- }
- return response;
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- @Override
- public Response createConfigurationData(final String identifier, final NormalizedNodeContext payload,
- final UriInfo uriInfo) {
- this.configPost.incrementAndGet();
- Response response = null;
- try {
- response = this.delegate.createConfigurationData(identifier, payload, uriInfo);
- if (response.getStatus() == Status.OK.getStatusCode()) {
- this.successPost.incrementAndGet();
- } else {
- this.failurePost.incrementAndGet();
- }
- } catch (final Exception e) {
- this.failurePost.incrementAndGet();
- throw e;
- }
- return response;
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- @Override
- public Response createConfigurationData(final NormalizedNodeContext payload, final UriInfo uriInfo) {
- this.configPost.incrementAndGet();
- Response response = null;
- try {
- response = this.delegate.createConfigurationData(payload, uriInfo);
- if (response.getStatus() == Status.OK.getStatusCode()) {
- this.successPost.incrementAndGet();
- } else {
- this.failurePost.incrementAndGet();
- }
- } catch (final Exception e) {
- this.failurePost.incrementAndGet();
- throw e;
- }
- return response;
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- @Override
- public Response deleteConfigurationData(final String identifier) {
- this.configDelete.incrementAndGet();
- Response response = null;
- try {
- response = this.delegate.deleteConfigurationData(identifier);
- if (response.getStatus() == Status.OK.getStatusCode()) {
- this.successDelete.incrementAndGet();
- } else {
- this.failureDelete.incrementAndGet();
- }
- } catch (final Exception e) {
- this.failureDelete.incrementAndGet();
- throw e;
- }
- return response;
- }
-
- @Override
- public NormalizedNodeContext subscribeToStream(final String identifier, final UriInfo uriInfo) {
- return this.delegate.subscribeToStream(identifier, uriInfo);
- }
-
- @Override
- public NormalizedNodeContext getAvailableStreams(final UriInfo uriInfo) {
- return this.delegate.getAvailableStreams(uriInfo);
- }
-
- @Override
- public PatchStatusContext patchConfigurationData(final String identifier, final PatchContext payload,
- final UriInfo uriInfo) {
- return this.delegate.patchConfigurationData(identifier, payload, uriInfo);
- }
-
- @Override
- public PatchStatusContext patchConfigurationData(final PatchContext payload, final UriInfo uriInfo) {
- return this.delegate.patchConfigurationData(payload, uriInfo);
- }
-
- public BigInteger getConfigDelete() {
- return BigInteger.valueOf(this.configDelete.get());
- }
-
- public BigInteger getConfigGet() {
- return BigInteger.valueOf(this.configGet.get());
- }
-
- public BigInteger getConfigPost() {
- return BigInteger.valueOf(this.configPost.get());
- }
-
- public BigInteger getConfigPut() {
- return BigInteger.valueOf(this.configPut.get());
- }
-
- public BigInteger getOperationalGet() {
- return BigInteger.valueOf(this.operationalGet.get());
- }
-
- public BigInteger getRpc() {
- return BigInteger.valueOf(this.rpc.get());
- }
-
- public BigInteger getSuccessGetConfig() {
- return BigInteger.valueOf(this.successGetConfig.get());
- }
-
- public BigInteger getSuccessGetOperational() {
- return BigInteger.valueOf(this.successGetOperational.get());
- }
-
- public BigInteger getSuccessPost() {
- return BigInteger.valueOf(this.successPost.get());
- }
-
- public BigInteger getSuccessPut() {
- return BigInteger.valueOf(this.successPut.get());
- }
-
- public BigInteger getSuccessDelete() {
- return BigInteger.valueOf(this.successDelete.get());
- }
-
- public BigInteger getFailureGetConfig() {
- return BigInteger.valueOf(this.failureGetConfig.get());
- }
-
- public BigInteger getFailureGetOperational() {
- return BigInteger.valueOf(this.failureGetOperational.get());
- }
-
- public BigInteger getFailurePost() {
- return BigInteger.valueOf(this.failurePost.get());
- }
-
- public BigInteger getFailurePut() {
- return BigInteger.valueOf(this.failurePut.get());
- }
-
- public BigInteger getFailureDelete() {
- return BigInteger.valueOf(this.failureDelete.get());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 Inocybe Technologies 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.sal.restconf.impl.jmx;
-
-public class Config {
- private Delete delete;
-
- private Post post;
-
- private Get get;
-
- private Put put;
-
- public Delete getDelete() {
- return delete;
- }
-
- public void setDelete(Delete delete) {
- this.delete = delete;
- }
-
- public Post getPost() {
- return post;
- }
-
- public void setPost(Post post) {
- this.post = post;
- }
-
- public Get getGet() {
- return get;
- }
-
- public void setGet(Get get) {
- this.get = get;
- }
-
- public Put getPut() {
- return put;
- }
-
- public void setPut(Put put) {
- this.put = put;
- }
-
- @Override
- public int hashCode() {
- return java.util.Objects.hash(delete, post, get, put);
-
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- final Config that = (Config) obj;
- if (!java.util.Objects.equals(delete, that.delete)) {
- return false;
- }
-
- if (!java.util.Objects.equals(post, that.post)) {
- return false;
- }
-
- if (!java.util.Objects.equals(get, that.get)) {
- return false;
- }
-
- return java.util.Objects.equals(put, that.put);
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 Inocybe Technologies 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.sal.restconf.impl.jmx;
-
-import java.math.BigInteger;
-
-public class Delete {
- private BigInteger successfulResponses;
-
- private BigInteger receivedRequests;
-
- private BigInteger failedResponses;
-
- public BigInteger getSuccessfulResponses() {
- return successfulResponses;
- }
-
- public void setSuccessfulResponses(BigInteger successfulResponses) {
- this.successfulResponses = successfulResponses;
- }
-
- public BigInteger getReceivedRequests() {
- return receivedRequests;
- }
-
- public void setReceivedRequests(BigInteger receivedRequests) {
- this.receivedRequests = receivedRequests;
- }
-
- public BigInteger getFailedResponses() {
- return failedResponses;
- }
-
- public void setFailedResponses(BigInteger failedResponses) {
- this.failedResponses = failedResponses;
- }
-
- @Override
- public int hashCode() {
- return java.util.Objects.hash(successfulResponses, receivedRequests, failedResponses);
-
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- final Delete that = (Delete) obj;
- if (!java.util.Objects.equals(successfulResponses, that.successfulResponses)) {
- return false;
- }
-
- if (!java.util.Objects.equals(receivedRequests, that.receivedRequests)) {
- return false;
- }
-
- return java.util.Objects.equals(failedResponses, that.failedResponses);
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 Inocybe Technologies 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.sal.restconf.impl.jmx;
-
-import java.math.BigInteger;
-
-public class Get {
- private BigInteger successfulResponses;
-
- private BigInteger receivedRequests;
-
- private BigInteger failedResponses;
-
- public BigInteger getSuccessfulResponses() {
- return successfulResponses;
- }
-
- public void setSuccessfulResponses(BigInteger successfulResponses) {
- this.successfulResponses = successfulResponses;
- }
-
- public BigInteger getReceivedRequests() {
- return receivedRequests;
- }
-
- public void setReceivedRequests(BigInteger receivedRequests) {
- this.receivedRequests = receivedRequests;
- }
-
- public BigInteger getFailedResponses() {
- return failedResponses;
- }
-
- public void setFailedResponses(BigInteger failedResponses) {
- this.failedResponses = failedResponses;
- }
-
- @Override
- public int hashCode() {
- return java.util.Objects.hash(successfulResponses, receivedRequests, failedResponses);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- final Get that = (Get) obj;
- if (!java.util.Objects.equals(successfulResponses, that.successfulResponses)) {
- return false;
- }
-
- if (!java.util.Objects.equals(receivedRequests, that.receivedRequests)) {
- return false;
- }
-
- return java.util.Objects.equals(failedResponses, that.failedResponses);
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 Inocybe Technologies 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.sal.restconf.impl.jmx;
-
-public class Operational {
- private Get get;
-
- public Get getGet() {
- return get;
- }
-
- public void setGet(Get get) {
- this.get = get;
- }
-
- @Override
- public int hashCode() {
- return java.util.Objects.hash(get);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- final Operational that = (Operational) obj;
- return java.util.Objects.equals(get, that.get);
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 Inocybe Technologies 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.sal.restconf.impl.jmx;
-
-import java.math.BigInteger;
-
-public class Post {
- private BigInteger successfulResponses;
-
- private BigInteger receivedRequests;
-
- private BigInteger failedResponses;
-
- public BigInteger getSuccessfulResponses() {
- return successfulResponses;
- }
-
- public void setSuccessfulResponses(BigInteger successfulResponses) {
- this.successfulResponses = successfulResponses;
- }
-
- public BigInteger getReceivedRequests() {
- return receivedRequests;
- }
-
- public void setReceivedRequests(BigInteger receivedRequests) {
- this.receivedRequests = receivedRequests;
- }
-
- public BigInteger getFailedResponses() {
- return failedResponses;
- }
-
- public void setFailedResponses(BigInteger failedResponses) {
- this.failedResponses = failedResponses;
- }
-
- @Override
- public int hashCode() {
- return java.util.Objects.hash(successfulResponses, receivedRequests, failedResponses);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- final Post that = (Post) obj;
- if (!java.util.Objects.equals(successfulResponses, that.successfulResponses)) {
- return false;
- }
-
- if (!java.util.Objects.equals(receivedRequests, that.receivedRequests)) {
- return false;
- }
-
- return java.util.Objects.equals(failedResponses, that.failedResponses);
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 Inocybe Technologies 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.sal.restconf.impl.jmx;
-
-import java.math.BigInteger;
-
-public class Put {
- private BigInteger successfulResponses;
-
- private BigInteger receivedRequests;
-
- private BigInteger failedResponses;
-
- public BigInteger getSuccessfulResponses() {
- return successfulResponses;
- }
-
- public void setSuccessfulResponses(BigInteger successfulResponses) {
- this.successfulResponses = successfulResponses;
- }
-
- public BigInteger getReceivedRequests() {
- return receivedRequests;
- }
-
- public void setReceivedRequests(BigInteger receivedRequests) {
- this.receivedRequests = receivedRequests;
- }
-
- public BigInteger getFailedResponses() {
- return failedResponses;
- }
-
- public void setFailedResponses(BigInteger failedResponses) {
- this.failedResponses = failedResponses;
- }
-
- @Override
- public int hashCode() {
- return java.util.Objects.hash(successfulResponses, receivedRequests, failedResponses);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- final Put that = (Put) obj;
- if (!java.util.Objects.equals(successfulResponses, that.successfulResponses)) {
- return false;
- }
-
- if (!java.util.Objects.equals(receivedRequests, that.receivedRequests)) {
- return false;
- }
-
- return java.util.Objects.equals(failedResponses, that.failedResponses);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 Inocybe Technologies 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.sal.restconf.impl.jmx;
-
-public interface RestConnectorRuntimeMXBean {
- Operational getOperational();
-
- Rpcs getRpcs();
-
- Config getConfig();
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 Inocybe Technologies 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.sal.restconf.impl.jmx;
-
-import java.math.BigInteger;
-
-public class Rpcs {
- private BigInteger successfulResponses;
-
- private BigInteger receivedRequests;
-
- private BigInteger failedResponses;
-
- public BigInteger getSuccessfulResponses() {
- return successfulResponses;
- }
-
- public void setSuccessfulResponses(BigInteger successfulResponses) {
- this.successfulResponses = successfulResponses;
- }
-
- public BigInteger getReceivedRequests() {
- return receivedRequests;
- }
-
- public void setReceivedRequests(BigInteger receivedRequests) {
- this.receivedRequests = receivedRequests;
- }
-
- public BigInteger getFailedResponses() {
- return failedResponses;
- }
-
- public void setFailedResponses(BigInteger failedResponses) {
- this.failedResponses = failedResponses;
- }
-
- @Override
- public int hashCode() {
- return java.util.Objects.hash(successfulResponses, receivedRequests, failedResponses);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- final Rpcs that = (Rpcs) obj;
- if (!java.util.Objects.equals(successfulResponses, that.successfulResponses)) {
- return false;
- }
-
- if (!java.util.Objects.equals(receivedRequests, that.receivedRequests)) {
- return false;
- }
-
- return java.util.Objects.equals(failedResponses, that.failedResponses);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 Inocybe Technologies 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
- */
-
-/**
- * This package contains the statistical JMX classes for the Draft02 restconf implementation. Originally these classes
- * were generated by the CSS code generator and were moved to this package on conversion to blueprint.
- */
-package org.opendaylight.netconf.sal.restconf.impl.jmx;
+++ /dev/null
-/*
- * 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.sal.restconf.impl;
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2018 Inocybe Technologies 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.sal.restconf.web;
-
-import javax.annotation.PreDestroy;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.servlet.ServletException;
-import org.opendaylight.aaa.filterchain.configuration.CustomFilterAdapterConfiguration;
-import org.opendaylight.aaa.filterchain.filters.CustomFilterAdapter;
-import org.opendaylight.aaa.web.FilterDetails;
-import org.opendaylight.aaa.web.ServletDetails;
-import org.opendaylight.aaa.web.WebContext;
-import org.opendaylight.aaa.web.WebContextBuilder;
-import org.opendaylight.aaa.web.WebContextRegistration;
-import org.opendaylight.aaa.web.WebContextSecurer;
-import org.opendaylight.aaa.web.WebServer;
-import org.opendaylight.aaa.web.servlet.ServletSupport;
-import org.opendaylight.netconf.sal.rest.impl.RestconfApplication;
-
-/**
- * Initializes the bierman-02 endpoint.
- *
- * @author Thomas Pantelis
- */
-@Singleton
-public class WebInitializer {
-
- private final WebContextRegistration registration;
-
- @Inject
- public WebInitializer(final WebServer webServer, final WebContextSecurer webContextSecurer,
- final ServletSupport servletSupport, final RestconfApplication webApp,
- final CustomFilterAdapterConfiguration customFilterAdapterConfig) throws ServletException {
-
- WebContextBuilder webContextBuilder = WebContext.builder().contextPath("restconf").supportsSessions(false)
- .addServlet(ServletDetails.builder().servlet(servletSupport.createHttpServletBuilder(webApp).build())
- .addUrlPattern("/*").build())
-
- // Allows user to add javax.servlet.Filter(s) in front of REST services
- .addFilter(FilterDetails.builder().filter(new CustomFilterAdapter(customFilterAdapterConfig))
- .addUrlPattern("/*").build());
-
- webContextSecurer.requireAuthentication(webContextBuilder, "/*");
-
- registration = webServer.registerWebContext(webContextBuilder.build());
- }
-
- @PreDestroy
- public void close() {
- if (registration != null) {
- registration.close();
- }
- }
-}
+++ /dev/null
-/*
- * 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.sal.streams.listeners;
-
-import com.google.common.eventbus.AsyncEventBus;
-import com.google.common.eventbus.EventBus;
-import io.netty.channel.Channel;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executors;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Features of subscribing part of both notifications.
- */
-abstract class AbstractCommonSubscriber extends AbstractQueryParams implements BaseListenerInterface {
-
- private static final Logger LOG = LoggerFactory.getLogger(AbstractCommonSubscriber.class);
-
- private final Set<Channel> subscribers = ConcurrentHashMap.newKeySet();
- private final EventBus eventBus;
-
- @SuppressWarnings("rawtypes")
- private EventBusChangeRecorder eventBusChangeRecorder;
- @SuppressWarnings("rawtypes")
- private ListenerRegistration registration;
-
- /**
- * Creating {@link EventBus}.
- */
- protected AbstractCommonSubscriber() {
- this.eventBus = new AsyncEventBus(Executors.newSingleThreadExecutor());
- }
-
- @Override
- public final boolean hasSubscribers() {
- return !this.subscribers.isEmpty();
- }
-
- @Override
- public final Set<Channel> getSubscribers() {
- return this.subscribers;
- }
-
- @Override
- public final void close() {
- if (registration != null) {
- this.registration.close();
- this.registration = null;
- }
-
- unregister();
- }
-
- /**
- * Creates event of type {@link EventType#REGISTER}, set {@link Channel}
- * subscriber to the event and post event into event bus.
- *
- * @param subscriber
- * Channel
- */
- public void addSubscriber(final Channel subscriber) {
- if (!subscriber.isActive()) {
- LOG.debug("Channel is not active between websocket server and subscriber {}", subscriber.remoteAddress());
- }
- final Event event = new Event(EventType.REGISTER);
- event.setSubscriber(subscriber);
- this.eventBus.post(event);
- }
-
- /**
- * Creates event of type {@link EventType#DEREGISTER}, sets {@link Channel}
- * subscriber to the event and posts event into event bus.
- *
- * @param subscriber subscriber channel
- */
- public void removeSubscriber(final Channel subscriber) {
- LOG.debug("Subscriber {} is removed.", subscriber.remoteAddress());
- final Event event = new Event(EventType.DEREGISTER);
- event.setSubscriber(subscriber);
- this.eventBus.post(event);
- }
-
- /**
- * Sets {@link ListenerRegistration} registration.
- *
- * @param registration
- * DOMDataChangeListener registration
- */
- @SuppressWarnings("rawtypes")
- public void setRegistration(final ListenerRegistration registration) {
- this.registration = registration;
- }
-
- /**
- * Checks if {@link ListenerRegistration} registration exist.
- *
- * @return True if exist, false otherwise.
- */
- public boolean isListening() {
- return this.registration != null;
- }
-
- /**
- * Creating and registering {@link EventBusChangeRecorder} of specific
- * listener on {@link EventBus}.
- *
- * @param listener
- * specific listener of notifications
- */
- @SuppressWarnings({ "unchecked", "rawtypes" })
- protected <T extends BaseListenerInterface> void register(final T listener) {
- this.eventBusChangeRecorder = new EventBusChangeRecorder(listener);
- this.eventBus.register(this.eventBusChangeRecorder);
- }
-
- /**
- * Post event to event bus.
- *
- * @param event
- * data of incoming notifications
- */
- protected void post(final Event event) {
- this.eventBus.post(event);
- }
-
- /**
- * Removes all subscribers and unregisters event bus change recorder form
- * event bus.
- */
- protected void unregister() {
- this.subscribers.clear();
- this.eventBus.unregister(this.eventBusChangeRecorder);
- }
-}
+++ /dev/null
-/*
- * 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.sal.streams.listeners;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.time.Instant;
-import java.time.OffsetDateTime;
-import java.time.ZoneId;
-import java.time.format.DateTimeFormatter;
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMResult;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-import org.opendaylight.yangtools.util.xml.UntrustedXML;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
-import org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-/**
- * Abstract class for processing and preparing data.
- *
- */
-abstract class AbstractNotificationsData {
- private static final Logger LOG = LoggerFactory.getLogger(AbstractNotificationsData.class);
- private static final TransformerFactory TF = TransformerFactory.newInstance();
- private static final XMLOutputFactory OF = XMLOutputFactory.newFactory();
-
- /**
- * Formats data specified by RFC3339.
- *
- * @param now time stamp
- * @return Data specified by RFC3339.
- */
- protected static String toRFC3339(final Instant now) {
- return DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(OffsetDateTime.ofInstant(now, ZoneId.systemDefault()));
- }
-
- /**
- * Creates {@link Document} document.
- *
- * @return {@link Document} document.
- */
- protected static Document createDocument() {
- return UntrustedXML.newDocumentBuilder().newDocument();
- }
-
- /**
- * Write normalized node to {@link DOMResult}.
- *
- * @param normalized
- * data
- * @param inference
- * SchemaInferenceStack state for the data
- * @return {@link DOMResult}
- */
- protected DOMResult writeNormalizedNode(final NormalizedNode normalized, final Inference inference)
- throws IOException, XMLStreamException {
- final Document doc = UntrustedXML.newDocumentBuilder().newDocument();
- final DOMResult result = new DOMResult(doc);
- NormalizedNodeWriter normalizedNodeWriter = null;
- NormalizedNodeStreamWriter normalizedNodeStreamWriter = null;
- XMLStreamWriter writer = null;
-
- try {
- writer = OF.createXMLStreamWriter(result);
- normalizedNodeStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(writer, inference);
- normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(normalizedNodeStreamWriter);
-
- normalizedNodeWriter.write(normalized);
-
- normalizedNodeWriter.flush();
- } finally {
- if (normalizedNodeWriter != null) {
- normalizedNodeWriter.close();
- }
- if (normalizedNodeStreamWriter != null) {
- normalizedNodeStreamWriter.close();
- }
- if (writer != null) {
- writer.close();
- }
- }
-
- return result;
- }
-
- /**
- * Generating base element of every notification.
- *
- * @param doc
- * base {@link Document}
- * @return element of {@link Document}
- */
- protected Element basePartDoc(final Document doc) {
- final Element notificationElement =
- doc.createElementNS("urn:ietf:params:xml:ns:netconf:notification:1.0", "notification");
-
- doc.appendChild(notificationElement);
-
- final Element eventTimeElement = doc.createElement("eventTime");
- eventTimeElement.setTextContent(toRFC3339(Instant.now()));
- notificationElement.appendChild(eventTimeElement);
-
- return notificationElement;
- }
-
- /**
- * Generating of {@link Document} transforming to string.
- *
- * @param doc
- * {@link Document} with data
- * @return - string from {@link Document}
- */
- protected String transformDoc(final Document doc) {
- final ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- try {
- final Transformer transformer = TF.newTransformer();
- transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
- transformer.setOutputProperty(OutputKeys.METHOD, "xml");
- transformer.setOutputProperty(OutputKeys.INDENT, "yes");
- transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
- transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
- transformer.transform(new DOMSource(doc), new StreamResult(out));
- } catch (final TransformerException e) {
- // FIXME: this should raise an exception
- final String msg = "Error during transformation of Document into String";
- LOG.error(msg, e);
- return msg;
- }
-
- return new String(out.toByteArray(), StandardCharsets.UTF_8);
- }
-}
+++ /dev/null
-/*
- * 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.sal.streams.listeners;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.VisibleForTesting;
-import java.io.StringReader;
-import java.time.Instant;
-import java.util.Optional;
-import javax.xml.XMLConstants;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathFactory;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.w3c.dom.Document;
-import org.xml.sax.InputSource;
-
-/**
- * Features of query parameters part of both notifications.
- *
- */
-abstract class AbstractQueryParams extends AbstractNotificationsData {
- // FIXME: BUG-7956: switch to using UntrustedXML
- private static final DocumentBuilderFactory DBF;
-
- static {
- final DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
- f.setCoalescing(true);
- f.setExpandEntityReferences(false);
- f.setIgnoringElementContentWhitespace(true);
- f.setIgnoringComments(true);
- f.setXIncludeAware(false);
- try {
- f.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
- f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
- f.setFeature("http://xml.org/sax/features/external-general-entities", false);
- f.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
- } catch (final ParserConfigurationException e) {
- throw new ExceptionInInitializerError(e);
- }
- DBF = f;
- }
-
- // FIXME: these should be final
- private Instant start = null;
- private Instant stop = null;
- private String filter = null;
- private boolean leafNodesOnly = false;
- private boolean skipNotificationData = false;
-
- @VisibleForTesting
- public final Instant getStart() {
- return start;
- }
-
- /**
- * Set query parameters for listener.
- *
- * @param start
- * start-time of getting notification
- * @param stop
- * stop-time of getting notification
- * @param filter
- * indicate which subset of all possible events are of interest
- * @param leafNodesOnly
- * if true, notifications will contain changes to leaf nodes only
- * @param skipNotificationData
- * if true, notification will not contain changed data
- */
- @SuppressWarnings("checkstyle:hiddenField")
- public void setQueryParams(final Instant start, final Optional<Instant> stop, final Optional<String> filter,
- final boolean leafNodesOnly, final boolean skipNotificationData) {
- this.start = requireNonNull(start);
- this.stop = stop.orElse(null);
- this.filter = filter.orElse(null);
- this.leafNodesOnly = leafNodesOnly;
- this.skipNotificationData = skipNotificationData;
- }
-
- /**
- * Check whether this query should only notify about leaf node changes.
- *
- * @return true if this query should only notify about leaf node changes
- */
- public boolean getLeafNodesOnly() {
- return leafNodesOnly;
- }
-
- /**
- * Check whether this query should notify changes without data.
- *
- * @return true if this query should notify about changes with data
- */
- public boolean isSkipNotificationData() {
- return skipNotificationData;
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- <T extends BaseListenerInterface> boolean checkStartStop(final Instant now, final T listener) {
- if (this.stop != null) {
- if (this.start.compareTo(now) < 0 && this.stop.compareTo(now) > 0) {
- return true;
- }
- if (this.stop.compareTo(now) < 0) {
- try {
- listener.close();
- } catch (final Exception e) {
- throw new RestconfDocumentedException("Problem with unregister listener." + e);
- }
- }
- } else if (this.start != null) {
- if (this.start.compareTo(now) < 0) {
- this.start = null;
- return true;
- }
- } else {
- return true;
- }
- return false;
- }
-
- /**
- * Check if is filter used and then prepare and post data do client.
- *
- * @param xml data of notification
- */
- @SuppressWarnings("checkstyle:IllegalCatch")
- boolean checkFilter(final String xml) {
- if (this.filter == null) {
- return true;
- }
-
- try {
- return parseFilterParam(xml);
- } catch (final Exception e) {
- throw new RestconfDocumentedException("Problem while parsing filter.", e);
- }
- }
-
- /**
- * Parse and evaluate filter value by xml.
- *
- * @return true or false - depends on filter expression and data of
- * notifiaction
- * @throws Exception if operation fails
- */
- private boolean parseFilterParam(final String xml) throws Exception {
- final Document docOfXml = DBF.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
- final XPath xPath = XPathFactory.newInstance().newXPath();
- // FIXME: BUG-7956: xPath.setNamespaceContext(nsContext);
- return (boolean) xPath.compile(this.filter).evaluate(docOfXml, XPathConstants.BOOLEAN);
- }
-}
+++ /dev/null
-/*
- * 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.sal.streams.listeners;
-
-import io.netty.channel.Channel;
-import java.util.Set;
-
-/**
- * Base interface for both listeners({@link ListenerAdapter},
- * {@link NotificationListenerAdapter}).
- */
-interface BaseListenerInterface extends AutoCloseable {
-
- /**
- * Return all subscribers of listener.
- *
- * @return set of subscribers
- */
- Set<Channel> getSubscribers();
-
- /**
- * Checks if exists at least one {@link Channel} subscriber.
- *
- * @return True if exist at least one {@link Channel} subscriber, false
- * otherwise.
- */
- boolean hasSubscribers();
-
- /**
- * Get name of stream.
- *
- * @return stream name
- */
- String getStreamName();
-
- /**
- * Get output type.
- *
- * @return outputType
- */
- String getOutputType();
-}
+++ /dev/null
-/*
- * 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.sal.streams.listeners;
-
-import io.netty.channel.Channel;
-
-/**
- * Represents event of specific {@link EventType} type, holds data and
- * {@link Channel} subscriber.
- */
-class Event {
- private final EventType type;
- private Channel subscriber;
- private String data;
-
- /**
- * Creates new event specified by {@link EventType} type.
- *
- * @param type
- * EventType
- */
- Event(final EventType type) {
- this.type = type;
- }
-
- /**
- * Gets the {@link Channel} subscriber.
- *
- * @return Channel
- */
- public Channel getSubscriber() {
- return this.subscriber;
- }
-
- /**
- * Sets subscriber for event.
- *
- * @param subscriber
- * Channel
- */
- public void setSubscriber(final Channel subscriber) {
- this.subscriber = subscriber;
- }
-
- /**
- * Gets event String.
- *
- * @return String representation of event data.
- */
- public String getData() {
- return this.data;
- }
-
- /**
- * Sets event data.
- *
- * @param data
- * String.
- */
- public void setData(final String data) {
- this.data = data;
- }
-
- /**
- * Gets event type.
- *
- * @return The type of the event.
- */
- public EventType getType() {
- return this.type;
- }
-}
+++ /dev/null
-/*
- * 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.sal.streams.listeners;
-
-import com.google.common.eventbus.Subscribe;
-import io.netty.channel.Channel;
-import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class EventBusChangeRecorder<T extends BaseListenerInterface> {
-
- private static final Logger LOG = LoggerFactory.getLogger(EventBusChangeRecorder.class);
- private final T listener;
-
- /**
- * Event bus change recorder of specific listener of notifications.
- *
- * @param listener
- * specific listener
- */
- EventBusChangeRecorder(final T listener) {
- this.listener = listener;
- }
-
- @Subscribe
- public void recordCustomerChange(final Event event) {
- if (event.getType() == EventType.REGISTER) {
- final Channel subscriber = event.getSubscriber();
- if (!this.listener.getSubscribers().contains(subscriber)) {
- this.listener.getSubscribers().add(subscriber);
- }
- } else if (event.getType() == EventType.DEREGISTER) {
- this.listener.getSubscribers().remove(event.getSubscriber());
- Notificator.removeListenerIfNoSubscriberExists(this.listener);
- } else if (event.getType() == EventType.NOTIFY) {
- for (final Channel subscriber : this.listener.getSubscribers()) {
- if (subscriber.isActive()) {
- LOG.debug("Data are sent to subscriber {}:", subscriber.remoteAddress());
- subscriber.writeAndFlush(new TextWebSocketFrame(event.getData()));
- } else {
- LOG.debug("Subscriber {} is removed - channel is not active yet.", subscriber.remoteAddress());
- this.listener.getSubscribers().remove(subscriber);
- }
- }
- }
- }
-}
+++ /dev/null
-/*
- * 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.sal.streams.listeners;
-
-/**
- * Type of the event.
- */
-enum EventType {
- REGISTER, DEREGISTER, NOTIFY
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, 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.sal.streams.listeners;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static java.util.Objects.requireNonNull;
-
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import java.io.IOException;
-import java.time.Instant;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Optional;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.transform.dom.DOMResult;
-import org.json.XML;
-import org.opendaylight.mdsal.dom.api.ClusteredDOMDataTreeChangeListener;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping.NotificationOutputType;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
-import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidate;
-import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidateNode;
-import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-/**
- * {@link ListenerAdapter} is responsible to track events, which occurred by
- * changing data in data source.
- */
-public class ListenerAdapter extends AbstractCommonSubscriber implements ClusteredDOMDataTreeChangeListener {
-
- private static final Logger LOG = LoggerFactory.getLogger(ListenerAdapter.class);
- private static final String DATA_CHANGE_EVENT = "data-change-event";
- private static final String PATH = "path";
- private static final String OPERATION = "operation";
-
- private final ControllerContext controllerContext;
- private final YangInstanceIdentifier path;
- private final String streamName;
- private final NotificationOutputType outputType;
-
- /**
- * Creates new {@link ListenerAdapter} listener specified by path and stream
- * name and register for subscribing.
- *
- * @param path
- * Path to data in data store.
- * @param streamName
- * The name of the stream.
- * @param outputType
- * Type of output on notification (JSON, XML)
- */
- @SuppressFBWarnings(value = "MC_OVERRIDABLE_METHOD_CALL_IN_CONSTRUCTOR", justification = "non-final for testing")
- ListenerAdapter(final YangInstanceIdentifier path, final String streamName,
- final NotificationOutputType outputType, final ControllerContext controllerContext) {
- this.outputType = requireNonNull(outputType);
- this.path = requireNonNull(path);
- checkArgument(streamName != null && !streamName.isEmpty());
- this.streamName = streamName;
- this.controllerContext = controllerContext;
- register(this);
- }
-
- @Override
- public void onInitialData() {
- // No-op
- }
-
- @Override
- public void onDataTreeChanged(final List<DataTreeCandidate> dataTreeCandidates) {
- final Instant now = Instant.now();
- if (!checkStartStop(now, this)) {
- return;
- }
-
- final String xml = prepareXml(dataTreeCandidates);
- if (checkFilter(xml)) {
- prepareAndPostData(xml);
- }
- }
-
- /**
- * Gets the name of the stream.
- *
- * @return The name of the stream.
- */
- @Override
- public String getStreamName() {
- return streamName;
- }
-
- @Override
- public String getOutputType() {
- return outputType.getName();
- }
-
- /**
- * Get path pointed to data in data store.
- *
- * @return Path pointed to data in data store.
- */
- public YangInstanceIdentifier getPath() {
- return path;
- }
-
- /**
- * Prepare data of notification and data to client.
- *
- * @param xml data
- */
- private void prepareAndPostData(final String xml) {
- final Event event = new Event(EventType.NOTIFY);
- if (outputType.equals(NotificationOutputType.JSON)) {
- event.setData(XML.toJSONObject(xml).toString());
- } else {
- event.setData(xml);
- }
- post(event);
- }
-
- /**
- * Tracks events of data change by customer.
- */
-
- /**
- * Prepare data in printable form and transform it to String.
- *
- * @return Data in printable form.
- */
- private String prepareXml(final Collection<DataTreeCandidate> candidates) {
- final EffectiveModelContext schemaContext = controllerContext.getGlobalSchema();
- final DataSchemaContextTree dataContextTree = DataSchemaContextTree.from(schemaContext);
- final Document doc = createDocument();
- final Element notificationElement = basePartDoc(doc);
-
- final Element dataChangedNotificationEventElement = doc.createElementNS(
- "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote", "data-changed-notification");
-
- addValuesToDataChangedNotificationEventElement(doc, dataChangedNotificationEventElement, candidates,
- schemaContext, dataContextTree);
- notificationElement.appendChild(dataChangedNotificationEventElement);
- return transformDoc(doc);
- }
-
- /**
- * Adds values to data changed notification event element.
- *
- * @param doc
- * {@link Document}
- * @param dataChangedNotificationEventElement
- * {@link Element}
- * @param dataTreeCandidates
- * {@link DataTreeCandidate}
- */
- private void addValuesToDataChangedNotificationEventElement(final Document doc,
- final Element dataChangedNotificationEventElement,
- final Collection<DataTreeCandidate> dataTreeCandidates,
- final EffectiveModelContext schemaContext, final DataSchemaContextTree dataSchemaContextTree) {
-
- for (DataTreeCandidate dataTreeCandidate : dataTreeCandidates) {
- DataTreeCandidateNode candidateNode = dataTreeCandidate.getRootNode();
- if (candidateNode == null) {
- continue;
- }
- YangInstanceIdentifier yiid = dataTreeCandidate.getRootPath();
-
- boolean isSkipNotificationData = this.isSkipNotificationData();
- if (isSkipNotificationData) {
- createCreatedChangedDataChangeEventElementWithoutData(doc,
- dataChangedNotificationEventElement, dataTreeCandidate.getRootNode());
- } else {
- addNodeToDataChangeNotificationEventElement(doc, dataChangedNotificationEventElement, candidateNode,
- yiid.getParent(), schemaContext, dataSchemaContextTree);
- }
- }
- }
-
- private void addNodeToDataChangeNotificationEventElement(final Document doc,
- final Element dataChangedNotificationEventElement, final DataTreeCandidateNode candidateNode,
- final YangInstanceIdentifier parentYiid, final EffectiveModelContext schemaContext,
- final DataSchemaContextTree dataSchemaContextTree) {
-
- Optional<NormalizedNode> optionalNormalizedNode = Optional.empty();
- switch (candidateNode.getModificationType()) {
- case APPEARED:
- case SUBTREE_MODIFIED:
- case WRITE:
- optionalNormalizedNode = candidateNode.getDataAfter();
- break;
- case DELETE:
- case DISAPPEARED:
- optionalNormalizedNode = candidateNode.getDataBefore();
- break;
- case UNMODIFIED:
- default:
- break;
- }
-
- if (optionalNormalizedNode.isEmpty()) {
- LOG.error("No node present in notification for {}", candidateNode);
- return;
- }
-
- NormalizedNode normalizedNode = optionalNormalizedNode.get();
- YangInstanceIdentifier yiid = YangInstanceIdentifier.builder(parentYiid)
- .append(normalizedNode.getIdentifier()).build();
-
- boolean isNodeMixin = controllerContext.isNodeMixin(yiid);
- boolean isSkippedNonLeaf = getLeafNodesOnly() && !(normalizedNode instanceof LeafNode);
- if (!isNodeMixin && !isSkippedNonLeaf) {
- Node node = null;
- switch (candidateNode.getModificationType()) {
- case APPEARED:
- case SUBTREE_MODIFIED:
- case WRITE:
- Operation op = candidateNode.getDataBefore().isPresent() ? Operation.UPDATED : Operation.CREATED;
- node = createCreatedChangedDataChangeEventElement(doc, yiid, normalizedNode, op,
- schemaContext, dataSchemaContextTree);
- break;
- case DELETE:
- case DISAPPEARED:
- node = createDataChangeEventElement(doc, yiid, Operation.DELETED);
- break;
- case UNMODIFIED:
- default:
- break;
- }
- if (node != null) {
- dataChangedNotificationEventElement.appendChild(node);
- }
- }
-
- for (DataTreeCandidateNode childNode : candidateNode.getChildNodes()) {
- addNodeToDataChangeNotificationEventElement(doc, dataChangedNotificationEventElement, childNode,
- yiid, schemaContext, dataSchemaContextTree);
- }
- }
-
- /**
- * Creates changed event element from data.
- *
- * @param doc
- * {@link Document}
- * @param dataPath
- * Path to data in data store.
- * @param operation
- * {@link Operation}
- * @return {@link Node} node represented by changed event element.
- */
- private Node createDataChangeEventElement(final Document doc, final YangInstanceIdentifier dataPath,
- final Operation operation) {
- final Element dataChangeEventElement = doc.createElement(DATA_CHANGE_EVENT);
- final Element pathElement = doc.createElement(PATH);
- addPathAsValueToElement(dataPath, pathElement);
- dataChangeEventElement.appendChild(pathElement);
-
- final Element operationElement = doc.createElement(OPERATION);
- operationElement.setTextContent(operation.value);
- dataChangeEventElement.appendChild(operationElement);
-
- return dataChangeEventElement;
- }
-
- /**
- * Creates data change notification element without data element.
- *
- * @param doc
- * {@link Document}
- * @param dataChangedNotificationEventElement
- * {@link Element}
- * @param candidateNode
- * {@link DataTreeCandidateNode}
- */
- private void createCreatedChangedDataChangeEventElementWithoutData(final Document doc,
- final Element dataChangedNotificationEventElement, final DataTreeCandidateNode candidateNode) {
- final Operation operation;
- switch (candidateNode.getModificationType()) {
- case APPEARED:
- case SUBTREE_MODIFIED:
- case WRITE:
- operation = candidateNode.getDataBefore().isPresent() ? Operation.UPDATED : Operation.CREATED;
- break;
- case DELETE:
- case DISAPPEARED:
- operation = Operation.DELETED;
- break;
- case UNMODIFIED:
- default:
- return;
- }
- Node dataChangeEventElement = createDataChangeEventElement(doc, getPath(), operation);
- dataChangedNotificationEventElement.appendChild(dataChangeEventElement);
-
- }
-
- private Node createCreatedChangedDataChangeEventElement(final Document doc,
- final YangInstanceIdentifier eventPath, final NormalizedNode normalized, final Operation operation,
- final EffectiveModelContext schemaContext, final DataSchemaContextTree dataSchemaContextTree) {
- final Element dataChangeEventElement = doc.createElement(DATA_CHANGE_EVENT);
- final Element pathElement = doc.createElement(PATH);
- addPathAsValueToElement(eventPath, pathElement);
- dataChangeEventElement.appendChild(pathElement);
-
- final Element operationElement = doc.createElement(OPERATION);
- operationElement.setTextContent(operation.value);
- dataChangeEventElement.appendChild(operationElement);
-
- final SchemaInferenceStack stack = dataSchemaContextTree.enterPath(eventPath).orElseThrow().stack();
- if (!(normalized instanceof MapEntryNode) && !(normalized instanceof UnkeyedListEntryNode)
- && !stack.isEmpty()) {
- stack.exit();
- }
-
- final var inference = stack.toInference();
-
- try {
- final DOMResult domResult = writeNormalizedNode(normalized, inference);
- final Node result = doc.importNode(domResult.getNode().getFirstChild(), true);
- final Element dataElement = doc.createElement("data");
- dataElement.appendChild(result);
- dataChangeEventElement.appendChild(dataElement);
- } catch (final IOException e) {
- LOG.error("Error in writer ", e);
- } catch (final XMLStreamException e) {
- LOG.error("Error processing stream", e);
- }
-
- return dataChangeEventElement;
- }
-
- /**
- * Adds path as value to element.
- *
- * @param dataPath
- * Path to data in data store.
- * @param element
- * {@link Element}
- */
- @SuppressWarnings("rawtypes")
- private void addPathAsValueToElement(final YangInstanceIdentifier dataPath, final Element element) {
- final YangInstanceIdentifier normalizedPath = controllerContext.toXpathRepresentation(dataPath);
- final StringBuilder textContent = new StringBuilder();
-
- for (final PathArgument pathArgument : normalizedPath.getPathArguments()) {
- if (pathArgument instanceof YangInstanceIdentifier.AugmentationIdentifier) {
- continue;
- }
- textContent.append("/");
- writeIdentifierWithNamespacePrefix(element, textContent, pathArgument.getNodeType());
- if (pathArgument instanceof NodeIdentifierWithPredicates) {
- for (final Entry<QName, Object> entry : ((NodeIdentifierWithPredicates) pathArgument).entrySet()) {
- final QName keyValue = entry.getKey();
- final String predicateValue = String.valueOf(entry.getValue());
- textContent.append("[");
- writeIdentifierWithNamespacePrefix(element, textContent, keyValue);
- textContent.append("='");
- textContent.append(predicateValue);
- textContent.append("'");
- textContent.append("]");
- }
- } else if (pathArgument instanceof NodeWithValue) {
- textContent.append("[.='");
- textContent.append(((NodeWithValue) pathArgument).getValue());
- textContent.append("'");
- textContent.append("]");
- }
- }
- element.setTextContent(textContent.toString());
- }
-
- /**
- * Writes identifier that consists of prefix and QName.
- *
- * @param element
- * {@link Element}
- * @param textContent
- * StringBuilder
- * @param qualifiedName
- * QName
- */
- private void writeIdentifierWithNamespacePrefix(final Element element, final StringBuilder textContent,
- final QName qualifiedName) {
- final Module module = controllerContext.getGlobalSchema().findModule(qualifiedName.getModule())
- .get();
-
- textContent.append(module.getName());
- textContent.append(":");
- textContent.append(qualifiedName.getLocalName());
- }
-
- /**
- * Consists of three types {@link Operation#CREATED},
- * {@link Operation#UPDATED} and {@link Operation#DELETED}.
- */
- private enum Operation {
- CREATED("created"), UPDATED("updated"), DELETED("deleted");
-
- private final String value;
-
- Operation(final String value) {
- this.value = value;
- }
- }
-}
+++ /dev/null
-/*
- * 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.sal.streams.listeners;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.time.Instant;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.transform.dom.DOMResult;
-import org.opendaylight.mdsal.dom.api.DOMNotification;
-import org.opendaylight.mdsal.dom.api.DOMNotificationListener;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
-import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier;
-import org.opendaylight.yangtools.yang.data.codec.gson.JSONNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.codec.gson.JsonWriterFactory;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-/**
- * {@link NotificationListenerAdapter} is responsible to track events on notifications.
- */
-public final class NotificationListenerAdapter extends AbstractCommonSubscriber implements DOMNotificationListener {
- private static final Logger LOG = LoggerFactory.getLogger(NotificationListenerAdapter.class);
-
- private final ControllerContext controllerContext;
- private final String streamName;
- private final Absolute path;
- private final String outputType;
-
- /**
- * Set path of listener and stream name, register event bus.
- *
- * @param path
- * path of notification
- * @param streamName
- * stream name of listener
- * @param outputType
- * type of output on notification (JSON, XML)
- */
- NotificationListenerAdapter(final Absolute path, final String streamName, final String outputType,
- final ControllerContext controllerContext) {
- register(this);
- this.outputType = requireNonNull(outputType);
- this.path = requireNonNull(path);
- checkArgument(streamName != null && !streamName.isEmpty());
- this.streamName = streamName;
- this.controllerContext = controllerContext;
- }
-
- /**
- * Get outputType of listener.
- *
- * @return the outputType
- */
- @Override
- public String getOutputType() {
- return outputType;
- }
-
- @Override
- public void onNotification(final DOMNotification notification) {
- final Instant now = Instant.now();
- if (!checkStartStop(now, this)) {
- return;
- }
-
- final EffectiveModelContext schemaContext = controllerContext.getGlobalSchema();
- final String xml = prepareXml(schemaContext, notification);
- if (checkFilter(xml)) {
- prepareAndPostData(outputType.equals("JSON") ? prepareJson(schemaContext, notification) : xml);
- }
- }
-
- /**
- * Get stream name of this listener.
- *
- * @return {@link String}
- */
- @Override
- public String getStreamName() {
- return streamName;
- }
-
- /**
- * Get schema path of notification.
- *
- * @return {@link Absolute} SchemaNodeIdentifier
- */
- public Absolute getSchemaPath() {
- return path;
- }
-
- /**
- * Prepare data of notification and data to client.
- *
- * @param data data
- */
- private void prepareAndPostData(final String data) {
- final Event event = new Event(EventType.NOTIFY);
- event.setData(data);
- post(event);
- }
-
- /**
- * Prepare json from notification data.
- *
- * @return json as {@link String}
- */
- @VisibleForTesting
- String prepareJson(final EffectiveModelContext schemaContext, final DOMNotification notification) {
- final JsonObject json = new JsonObject();
- json.add("ietf-restconf:notification", JsonParser.parseString(writeBodyToString(schemaContext, notification)));
- json.addProperty("event-time", ListenerAdapter.toRFC3339(Instant.now()));
- return json.toString();
- }
-
- private static String writeBodyToString(final EffectiveModelContext schemaContext,
- final DOMNotification notification) {
- final Writer writer = new StringWriter();
- final NormalizedNodeStreamWriter jsonStream = JSONNormalizedNodeStreamWriter.createExclusiveWriter(
- JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02.getShared(schemaContext),
- notification.getType(), null, JsonWriterFactory.createJsonWriter(writer));
- final NormalizedNodeWriter nodeWriter = NormalizedNodeWriter.forStreamWriter(jsonStream);
- try {
- nodeWriter.write(notification.getBody());
- nodeWriter.close();
- } catch (final IOException e) {
- throw new RestconfDocumentedException("Problem while writing body of notification to JSON. ", e);
- }
- return writer.toString();
- }
-
- private String prepareXml(final EffectiveModelContext schemaContext, final DOMNotification notification) {
- final Document doc = createDocument();
- final Element notificationElement = basePartDoc(doc);
-
- final Element notificationEventElement = doc.createElementNS(
- "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote", "create-notification-stream");
- addValuesToNotificationEventElement(doc, notificationEventElement, schemaContext, notification);
- notificationElement.appendChild(notificationEventElement);
-
- return transformDoc(doc);
- }
-
- private void addValuesToNotificationEventElement(final Document doc, final Element element,
- final EffectiveModelContext schemaContext, final DOMNotification notification) {
- try {
- final DOMResult domResult = writeNormalizedNode(notification.getBody(),
- SchemaInferenceStack.of(schemaContext, path).toInference());
- final Node result = doc.importNode(domResult.getNode().getFirstChild(), true);
- final Element dataElement = doc.createElement("notification");
- dataElement.appendChild(result);
- element.appendChild(dataElement);
- } catch (final IOException e) {
- LOG.error("Error in writer ", e);
- } catch (final XMLStreamException e) {
- LOG.error("Error processing stream", e);
- }
- }
-}
+++ /dev/null
-/*
- * 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.sal.streams.listeners;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping.NotificationOutputType;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
-import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * {@link Notificator} is responsible to create, remove and find
- * {@link ListenerAdapter} listener.
- */
-public final class Notificator {
-
- private static Map<String, ListenerAdapter> dataChangeListener = new ConcurrentHashMap<>();
- private static Map<String, List<NotificationListenerAdapter>> notificationListenersByStreamName =
- new ConcurrentHashMap<>();
-
- private static final Logger LOG = LoggerFactory.getLogger(Notificator.class);
- private static final Lock LOCK = new ReentrantLock();
-
- private Notificator() {
- }
-
- /**
- * Returns list of all stream names.
- */
- public static Set<String> getStreamNames() {
- return dataChangeListener.keySet();
- }
-
- /**
- * Gets {@link ListenerAdapter} specified by stream name.
- *
- * @param streamName
- * The name of the stream.
- * @return {@link ListenerAdapter} specified by stream name.
- */
- public static ListenerAdapter getListenerFor(final String streamName) {
- return dataChangeListener.get(streamName);
- }
-
- /**
- * Checks if the listener specified by {@link YangInstanceIdentifier} path exist.
- *
- * @param streamName name of the stream
- * @return True if the listener exist, false otherwise.
- */
- public static boolean existListenerFor(final String streamName) {
- return dataChangeListener.containsKey(streamName);
- }
-
- /**
- * Creates new {@link ListenerAdapter} listener from
- * {@link YangInstanceIdentifier} path and stream name.
- *
- * @param path
- * Path to data in data repository.
- * @param streamName
- * The name of the stream.
- * @param outputType
- * Spcific type of output for notifications - XML or JSON
- * @return New {@link ListenerAdapter} listener from
- * {@link YangInstanceIdentifier} path and stream name.
- */
- public static ListenerAdapter createListener(final YangInstanceIdentifier path, final String streamName,
- final NotificationOutputType outputType, final ControllerContext controllerContext) {
- final ListenerAdapter listener = new ListenerAdapter(path, streamName, outputType, controllerContext);
- try {
- LOCK.lock();
- dataChangeListener.put(streamName, listener);
- } finally {
- LOCK.unlock();
- }
- return listener;
- }
-
- /**
- * Looks for listener determined by {@link YangInstanceIdentifier} path and removes it.
- * Creates String representation of stream name from URI. Removes slash from URI in start and end position.
- *
- * @param uri
- * URI for creation stream name.
- * @return String representation of stream name.
- */
- public static String createStreamNameFromUri(final String uri) {
- if (uri == null) {
- return null;
- }
- String result = uri;
- if (result.startsWith("/")) {
- result = result.substring(1);
- }
- if (result.endsWith("/")) {
- result = result.substring(0, result.length() - 1);
- }
- return result;
- }
-
- /**
- * Removes all listeners.
- */
- @SuppressWarnings("checkstyle:IllegalCatch")
- public static void removeAllListeners() {
- for (final ListenerAdapter listener : dataChangeListener.values()) {
- try {
- listener.close();
- } catch (final Exception e) {
- LOG.error("Failed to close listener", e);
- }
- }
- try {
- LOCK.lock();
- dataChangeListener = new ConcurrentHashMap<>();
- } finally {
- LOCK.unlock();
- }
- }
-
- /**
- * Delete {@link ListenerAdapter} listener specified in parameter.
- *
- * @param <T>
- *
- * @param listener
- * ListenerAdapter
- */
- @SuppressWarnings("checkstyle:IllegalCatch")
- private static <T extends BaseListenerInterface> void deleteListener(final T listener) {
- if (listener != null) {
- try {
- listener.close();
- } catch (final Exception e) {
- LOG.error("Failed to close listener", e);
- }
- try {
- LOCK.lock();
- dataChangeListener.remove(listener.getStreamName());
- } finally {
- LOCK.unlock();
- }
- }
- }
-
- /**
- * Check if the listener specified by qnames of request exist.
- *
- * @param streamName
- * name of stream
- * @return True if the listener exist, false otherwise.
- */
- public static boolean existNotificationListenerFor(final String streamName) {
- return notificationListenersByStreamName.containsKey(streamName);
- }
-
- /**
- * Prepare listener for notification ({@link NotificationDefinition}).
- *
- * @param paths
- * paths of notifications
- * @param streamName
- * name of stream (generated by paths)
- * @param outputType
- * type of output for onNotification - XML or JSON
- * @return List of {@link NotificationListenerAdapter} by paths
- */
- public static List<NotificationListenerAdapter> createNotificationListener(final List<Absolute> paths,
- final String streamName, final String outputType, final ControllerContext controllerContext) {
- final List<NotificationListenerAdapter> listListeners = new ArrayList<>();
- for (final Absolute path : paths) {
- final NotificationListenerAdapter listener =
- new NotificationListenerAdapter(path, streamName, outputType, controllerContext);
- listListeners.add(listener);
- }
- try {
- LOCK.lock();
- notificationListenersByStreamName.put(streamName, listListeners);
- } finally {
- LOCK.unlock();
- }
- return listListeners;
- }
-
- public static <T extends BaseListenerInterface> void removeListenerIfNoSubscriberExists(final T listener) {
- if (!listener.hasSubscribers()) {
- if (listener instanceof NotificationListenerAdapter) {
- deleteNotificationListener(listener);
- } else {
- deleteListener(listener);
- }
- }
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- private static <T extends BaseListenerInterface> void deleteNotificationListener(final T listener) {
- if (listener != null) {
- try {
- listener.close();
- } catch (final Exception e) {
- LOG.error("Failed to close listener", e);
- }
- try {
- LOCK.lock();
- notificationListenersByStreamName.remove(listener.getStreamName());
- } finally {
- LOCK.unlock();
- }
- }
- }
-
- public static List<NotificationListenerAdapter> getNotificationListenerFor(final String streamName) {
- return notificationListenersByStreamName.get(streamName);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 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.sal.streams.websockets;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
-
-import io.netty.bootstrap.ServerBootstrap;
-import io.netty.channel.Channel;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.nio.NioServerSocketChannel;
-import org.opendaylight.netconf.sal.streams.listeners.Notificator;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * {@link WebSocketServer} is the singleton responsible for starting and stopping the
- * web socket server.
- */
-public final class WebSocketServer implements Runnable {
-
- private static final Logger LOG = LoggerFactory.getLogger(WebSocketServer.class);
-
- private static final String DEFAULT_ADDRESS = "0.0.0.0";
-
- private static WebSocketServer instance = null;
-
- private final String address;
- private final int port;
-
- private EventLoopGroup bossGroup;
- private EventLoopGroup workerGroup;
-
-
- private WebSocketServer(final String address, final int port) {
- this.address = address;
- this.port = port;
- }
-
- /**
- * Create singleton instance of {@link WebSocketServer}.
- *
- * @param port TCP port used for this server
- * @return instance of {@link WebSocketServer}
- */
- private static WebSocketServer createInstance(final int port) {
- instance = createInstance(DEFAULT_ADDRESS, port);
- return instance;
- }
-
- public static WebSocketServer createInstance(final String address, final int port) {
- checkState(instance == null, "createInstance() has already been called");
- checkArgument(port >= 1024, "Privileged port (below 1024) is not allowed");
-
- instance = new WebSocketServer(requireNonNull(address, "Address cannot be null."), port);
- LOG.info("Created WebSocketServer on {}:{}", address, port);
- return instance;
- }
-
- /**
- * Get the websocket of TCP port.
- *
- * @return websocket TCP port
- */
- public int getPort() {
- return port;
- }
-
- /**
- * Get instance of {@link WebSocketServer} created by {@link #createInstance(int)}.
- *
- * @return instance of {@link WebSocketServer}
- */
- public static WebSocketServer getInstance() {
- return requireNonNull(instance, "createInstance() must be called prior to getInstance()");
- }
-
- /**
- * Get instance of {@link WebSocketServer} created by {@link #createInstance(int)}.
- * If an instance doesnt exist create one with the provided fallback port.
- *
- * @return instance of {@link WebSocketServer}
- */
- public static WebSocketServer getInstance(final int fallbackPort) {
- if (instance != null) {
- return instance;
- }
-
- LOG.warn("No instance for WebSocketServer found, creating one with a fallback port: {}", fallbackPort);
- return createInstance(fallbackPort);
- }
-
- /**
- * Destroy the existing instance.
- */
- public static void destroyInstance() {
- checkState(instance != null, "createInstance() must be called prior to destroyInstance()");
-
- instance.stop();
- instance = null;
- LOG.info("Destroyed WebSocketServer.");
- }
-
- @Override
- @SuppressWarnings("checkstyle:IllegalCatch")
- public void run() {
- bossGroup = new NioEventLoopGroup();
- workerGroup = new NioEventLoopGroup();
- try {
- final ServerBootstrap serverBootstrap = new ServerBootstrap();
- serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
- .childHandler(new WebSocketServerInitializer());
-
- final Channel channel = serverBootstrap.bind(address, port).sync().channel();
- LOG.info("Web socket server started at address {}, port {}.", address, port);
-
- channel.closeFuture().sync();
- } catch (final InterruptedException e) {
- LOG.error("Web socket server encountered an error during startup attempt on port {}", port, e);
- } catch (Throwable throwable) {
- // sync() re-throws exceptions declared as Throwable, so the compiler doesn't see them
- LOG.error("Error while binding to address {}, port {}", address, port, throwable);
- throw throwable;
- } finally {
- stop();
- }
- }
-
- /**
- * Stops the web socket server and removes all listeners.
- */
- private void stop() {
- LOG.info("Stopping the web socket server instance on port {}", port);
- Notificator.removeAllListeners();
- if (bossGroup != null) {
- bossGroup.shutdownGracefully();
- bossGroup = null;
- }
- if (workerGroup != null) {
- workerGroup.shutdownGracefully();
- workerGroup = null;
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 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.sal.streams.websockets;
-
-import static io.netty.handler.codec.http.HttpHeaderNames.HOST;
-import static io.netty.handler.codec.http.HttpMethod.GET;
-import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;
-import static io.netty.handler.codec.http.HttpResponseStatus.FORBIDDEN;
-import static io.netty.handler.codec.http.HttpResponseStatus.INTERNAL_SERVER_ERROR;
-import static io.netty.handler.codec.http.HttpResponseStatus.OK;
-import static io.netty.handler.codec.http.HttpUtil.isKeepAlive;
-import static io.netty.handler.codec.http.HttpUtil.setContentLength;
-import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
-
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelFutureListener;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.SimpleChannelInboundHandler;
-import io.netty.handler.codec.http.DefaultFullHttpResponse;
-import io.netty.handler.codec.http.FullHttpRequest;
-import io.netty.handler.codec.http.FullHttpResponse;
-import io.netty.handler.codec.http.HttpRequest;
-import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
-import io.netty.handler.codec.http.websocketx.PingWebSocketFrame;
-import io.netty.handler.codec.http.websocketx.PongWebSocketFrame;
-import io.netty.handler.codec.http.websocketx.WebSocketFrame;
-import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
-import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory;
-import io.netty.util.CharsetUtil;
-import java.util.List;
-import org.opendaylight.netconf.sal.restconf.impl.RestconfImpl;
-import org.opendaylight.netconf.sal.streams.listeners.ListenerAdapter;
-import org.opendaylight.netconf.sal.streams.listeners.NotificationListenerAdapter;
-import org.opendaylight.netconf.sal.streams.listeners.Notificator;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * {@link WebSocketServerHandler} is implementation of {@link SimpleChannelInboundHandler} which allow handle
- * {@link FullHttpRequest} and {@link WebSocketFrame} messages.
- */
-public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object> {
- private static final Logger LOG = LoggerFactory.getLogger(WebSocketServerHandler.class);
-
- private WebSocketServerHandshaker handshaker;
-
- @Override
- protected void channelRead0(final ChannelHandlerContext ctx, final Object msg) {
- if (msg instanceof FullHttpRequest) {
- handleHttpRequest(ctx, (FullHttpRequest) msg);
- } else if (msg instanceof WebSocketFrame) {
- handleWebSocketFrame(ctx, (WebSocketFrame) msg);
- }
- }
-
- /**
- * Checks if HTTP request method is GET and if is possible to decode HTTP result of request.
- *
- * @param ctx ChannelHandlerContext
- * @param req FullHttpRequest
- */
- private void handleHttpRequest(final ChannelHandlerContext ctx, final FullHttpRequest req) {
- // Handle a bad request.
- if (!req.decoderResult().isSuccess()) {
- sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, BAD_REQUEST));
- return;
- }
-
- // Allow only GET methods.
- if (req.method() != GET) {
- sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, FORBIDDEN));
- return;
- }
-
- final String streamName = Notificator.createStreamNameFromUri(req.uri());
- if (streamName.contains(RestconfImpl.DATA_SUBSCR)) {
- final ListenerAdapter listener = Notificator.getListenerFor(streamName);
- if (listener != null) {
- listener.addSubscriber(ctx.channel());
- LOG.debug("Subscriber successfully registered.");
- } else {
- LOG.error("Listener for stream with name '{}' was not found.", streamName);
- sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, INTERNAL_SERVER_ERROR));
- }
- } else if (streamName.contains(RestconfImpl.NOTIFICATION_STREAM)) {
- final List<NotificationListenerAdapter> listeners = Notificator.getNotificationListenerFor(streamName);
- if (listeners != null && !listeners.isEmpty()) {
- for (final NotificationListenerAdapter listener : listeners) {
- listener.addSubscriber(ctx.channel());
- LOG.debug("Subscriber successfully registered.");
- }
- } else {
- LOG.error("Listener for stream with name '{}' was not found.", streamName);
- sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, INTERNAL_SERVER_ERROR));
- }
- }
-
- // Handshake
- final WebSocketServerHandshakerFactory wsFactory =
- new WebSocketServerHandshakerFactory(getWebSocketLocation(req),
- null, false);
- this.handshaker = wsFactory.newHandshaker(req);
- if (this.handshaker == null) {
- WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
- } else {
- this.handshaker.handshake(ctx.channel(), req);
- }
- }
-
- /**
- * Checks response status, send response and close connection if necessary.
- *
- * @param ctx ChannelHandlerContext
- * @param req HttpRequest
- * @param res FullHttpResponse
- */
- private static void sendHttpResponse(final ChannelHandlerContext ctx, final HttpRequest req,
- final FullHttpResponse res) {
- // Generate an error page if response getStatus code is not OK (200).
- final boolean notOkay = !OK.equals(res.status());
- if (notOkay) {
- res.content().writeCharSequence(res.status().toString(), CharsetUtil.UTF_8);
- setContentLength(res, res.content().readableBytes());
- }
-
- // Send the response and close the connection if necessary.
- final ChannelFuture f = ctx.channel().writeAndFlush(res);
- if (notOkay || !isKeepAlive(req)) {
- f.addListener(ChannelFutureListener.CLOSE);
- }
- }
-
- /**
- * Handles web socket frame.
- *
- * @param ctx {@link ChannelHandlerContext}
- * @param frame {@link WebSocketFrame}
- */
- private void handleWebSocketFrame(final ChannelHandlerContext ctx, final WebSocketFrame frame) {
- if (frame instanceof CloseWebSocketFrame) {
- this.handshaker.close(ctx.channel(), (CloseWebSocketFrame) frame.retain());
- final String streamName = Notificator.createStreamNameFromUri(((CloseWebSocketFrame) frame).reasonText());
- if (streamName.contains(RestconfImpl.DATA_SUBSCR)) {
- final ListenerAdapter listener = Notificator.getListenerFor(streamName);
- if (listener != null) {
- listener.removeSubscriber(ctx.channel());
- LOG.debug("Subscriber successfully registered.");
-
- Notificator.removeListenerIfNoSubscriberExists(listener);
- }
- } else if (streamName.contains(RestconfImpl.NOTIFICATION_STREAM)) {
- final List<NotificationListenerAdapter> listeners = Notificator.getNotificationListenerFor(streamName);
- if (listeners != null && !listeners.isEmpty()) {
- for (final NotificationListenerAdapter listener : listeners) {
- listener.removeSubscriber(ctx.channel());
- }
- }
- }
- return;
- } else if (frame instanceof PingWebSocketFrame) {
- ctx.channel().writeAndFlush(new PongWebSocketFrame(frame.content().retain()));
- return;
- }
- }
-
- @Override
- public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) {
- ctx.close();
- }
-
- /**
- * Get web socket location from HTTP request.
- *
- * @param req HTTP request from which the location will be returned
- * @return String representation of web socket location.
- */
- private static String getWebSocketLocation(final HttpRequest req) {
- return "ws://" + req.headers().get(HOST) + req.uri();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 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.sal.streams.websockets;
-
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.ChannelPipeline;
-import io.netty.channel.socket.SocketChannel;
-import io.netty.handler.codec.http.HttpObjectAggregator;
-import io.netty.handler.codec.http.HttpServerCodec;
-
-/**
- * {@link WebSocketServerInitializer} is used to setup the {@link ChannelPipeline} of a {@link io.netty.channel.Channel}
- * .
- */
-public class WebSocketServerInitializer extends ChannelInitializer<SocketChannel> {
-
- @Override
- protected void initChannel(final SocketChannel ch) {
- ChannelPipeline pipeline = ch.pipeline();
- pipeline.addLast("codec-http", new HttpServerCodec());
- pipeline.addLast("aggregator", new HttpObjectAggregator(65536));
- pipeline.addLast("handler", new WebSocketServerHandler());
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Brocade Communications 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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev131019;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev131019.DatastoreIdentifier.Enumeration;
-
-
-/**
- **/
-public class DatastoreIdentifierBuilder {
-
- public static DatastoreIdentifier getDefaultInstance(final String defaultValue) {
- return new DatastoreIdentifier(Enumeration.valueOf(defaultValue));
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev131019.restconf.restconf.modules;
-
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev131019.restconf.restconf.modules.Module.Revision;
-
-/**
- * The purpose of generated class in src/main/java for Union types is to create
- * new instances of unions from a string representation. In some cases it is
- * very difficult to automate it since there can be unions such as (uint32 -
- * uint16), or (string - uint32).
- *
- * The reason behind putting it under src/main/java is: This class is generated
- * in form of a stub and needs to be finished by the user. This class is
- * generated only once to prevent loss of user code.
- *
- */
-public class ModuleRevisionBuilder {
-
- public static Revision getDefaultInstance(java.lang.String defaultValue) {
- return RevisionBuilder.getDefaultInstance(defaultValue);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Brocade Communications 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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev131019.restconf.restconf.modules;
-
-import java.util.regex.Pattern;
-
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev131019.RevisionIdentifier;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev131019.restconf.restconf.modules.Module.Revision;
-
-/**
-**/
-public class RevisionBuilder {
-
- /**
- * Defines the pattern for revisions. NOTE: This pattern will likely be
- * updated in future versions of the ietf and should be adjusted accordingly
- */
- private static final Pattern REVISION_PATTERN = Pattern.compile("\\d{4}-\\d{2}-\\d{2}");
-
- public static Revision getDefaultInstance(String defaultValue) {
-
- if (defaultValue != null) {
- if (REVISION_PATTERN.matcher(defaultValue).matches()) {
- RevisionIdentifier id = new RevisionIdentifier(defaultValue);
- return new Revision(id);
- }
- if (defaultValue.isEmpty()) {
- return new Revision(defaultValue);
- }
- }
-
- throw new IllegalArgumentException("Cannot create Revision from " + defaultValue
- + ". Default value does not match pattern " + REVISION_PATTERN.pattern()
- + " or empty string.");
- }
-
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (c) 2017 Inocybe Technologies 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
--->
-<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
- xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0">
- <!-- Restconf providers -->
- <cm:property-placeholder persistent-id="org.opendaylight.restconf" update-strategy="reload">
- <cm:default-properties>
- <cm:property name="websocket-address" value="0.0.0.0"/>
- <cm:property name="websocket-port" value="8185"/>
- </cm:default-properties>
- </cm:property-placeholder>
-
- <bean id="webSocketPort" class="org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber" factory-method="getDefaultInstance">
- <argument value="${websocket-port}"/>
- </bean>
-
- <bean id="webSocketAddress" class="org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress">
- <argument value="${websocket-address}"/>
- </bean>
-
- <bean id="restconfProviderDraft02" class="org.opendaylight.netconf.sal.restconf.impl.RestconfProviderImpl"
- init-method="start" destroy-method="close">
- <argument ref="statisticsRestconfServiceWrapper"/>
- <argument ref="webSocketAddress"/>
- <argument ref="webSocketPort"/>
- </bean>
-
- <bean id="brokerFacade" class="org.opendaylight.netconf.sal.restconf.impl.BrokerFacade" destroy-method="close">
- <argument ref="dOMRpcService"/>
- <argument ref="dOMDataBroker"/>
- <argument ref="dOMNotificationService"/>
- <argument ref="controllerContext"/>
- </bean>
- <bean id="controllerContext" class="org.opendaylight.netconf.sal.restconf.impl.ControllerContext" destroy-method="close">
- <argument ref="dOMSchemaService"/>
- <argument ref="dOMMountPointService"/>
- <argument ref="dOMSchemaService"/>
- </bean>
- <bean id="jSONRestconfServiceImpl" class="org.opendaylight.netconf.sal.restconf.impl.JSONRestconfServiceImpl">
- <argument ref="controllerContext"/>
- <argument ref="restconfImpl"/>
- </bean>
- <bean id="restconfApplication" class="org.opendaylight.netconf.sal.rest.impl.RestconfApplication">
- <argument ref="controllerContext"/>
- <argument ref="statisticsRestconfServiceWrapper"/>
- </bean>
- <bean id="restconfImpl" class="org.opendaylight.netconf.sal.restconf.impl.RestconfImpl">
- <argument ref="brokerFacade"/>
- <argument ref="controllerContext"/>
- </bean>
- <bean id="statisticsRestconfServiceWrapper" class="org.opendaylight.netconf.sal.restconf.impl.StatisticsRestconfServiceWrapper">
- <argument ref="restconfImpl"/>
- </bean>
- <bean id="webInitializer" class="org.opendaylight.netconf.sal.restconf.web.WebInitializer" destroy-method="close">
- <argument ref="webServer"/>
- <argument ref="webContextSecurer"/>
- <argument ref="servletSupport"/>
- <argument ref="restconfApplication"/>
- <argument ref="customFilterAdapterConfiguration"/>
- </bean>
-
- <reference id="customFilterAdapterConfiguration" interface="org.opendaylight.aaa.filterchain.configuration.CustomFilterAdapterConfiguration"/>
- <reference id="webContextSecurer" interface="org.opendaylight.aaa.web.WebContextSecurer"/>
- <reference id="webServer" interface="org.opendaylight.aaa.web.WebServer"/>
- <reference id="servletSupport" interface="org.opendaylight.aaa.web.servlet.ServletSupport"/>
- <reference id="dOMDataBroker" interface="org.opendaylight.mdsal.dom.api.DOMDataBroker"/>
- <reference id="dOMMountPointService" interface="org.opendaylight.mdsal.dom.api.DOMMountPointService"/>
- <reference id="dOMNotificationService" interface="org.opendaylight.mdsal.dom.api.DOMNotificationService"/>
- <reference id="dOMRpcService" interface="org.opendaylight.mdsal.dom.api.DOMRpcService"/>
- <reference id="dOMSchemaService" interface="org.opendaylight.mdsal.dom.api.DOMSchemaService"/>
- <service ref="jSONRestconfServiceImpl" interface="org.opendaylight.netconf.sal.restconf.api.JSONRestconfService"/>
-</blueprint>
+++ /dev/null
-module ietf-restconf {
- namespace "urn:ietf:params:xml:ns:yang:ietf-restconf";
- prefix "restconf";
-
- import ietf-yang-types { prefix yang; revision-date 2013-07-15; }
- import ietf-inet-types { prefix inet; }
-
- organization
- "IETF NETCONF (Network Configuration) Working Group";
-
- contact
- "Editor: Andy Bierman
- <mailto:andy@yumaworks.com>
-
- Editor: Martin Bjorklund
- <mailto:mbj@tail-f.com>
-
- Editor: Kent Watsen
- <mailto:kwatsen@juniper.net>
-
- Editor: Rex Fernando
- <mailto:rex@cisco.com>";
-
- description
- "This module contains conceptual YANG specifications
- for the YANG Patch and error content that is used in
- RESTCONF protocol messages. A conceptual container
- representing the RESTCONF API nodes (media type
- application/yang.api).
-
- Note that the YANG definitions within this module do not
- represent configuration data of any kind.
- The YANG grouping statements provide a normative syntax
- for XML and JSON message encoding purposes.
-
- 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 XXXX; see
- the RFC itself for full legal notices.";
-
- // RFC Ed.: replace XXXX with actual RFC number and remove this
- // note.
-
- // RFC Ed.: remove this note
- // Note: extracted from draft-bierman-netconf-restconf-02.txt
-
- // RFC Ed.: update the date below with the date of RFC publication
- // and remove this note.
- revision 2013-10-19 {
- description
- "Initial revision.";
- reference
- "RFC XXXX: RESTCONF Protocol.";
- }
-
- typedef data-resource-identifier {
- type string {
- length "1 .. max";
- }
- description
- "Contains a Data Resource Identifier formatted string
- to identify a specific data node. The data node that
- uses this data type SHOULD define the document root
- for data resource identifiers. The default document
- root is the target datastore conceptual root node.
- Data resource identifiers are defined relative to
- this document root.";
- reference
- "RFC XXXX: [sec. 5.3.1.1 ABNF For Data Resource Identifiers]";
- }
-
- // this typedef is TBD; not currently used
- typedef datastore-identifier {
- type union {
- type enumeration {
- enum candidate {
- description
- "Identifies the NETCONF shared candidate datastore.";
- reference
- "RFC 6241, section 8.3";
- }
- enum running {
- description
- "Identifies the NETCONF running datastore.";
- reference
- "RFC 6241, section 5.1";
- }
- enum startup {
- description
- "Identifies the NETCONF startup datastore.";
- reference
- "RFC 6241, section 8.7";
- }
- }
- type string;
- }
- description
- "Contains a string to identify a specific datastore.
- The enumerated datastore identifier values are
- reserved for standard datastore names.";
- }
-
- typedef revision-identifier {
- type string {
- pattern '\d{4}-\d{2}-\d{2}';
- }
- description
- "Represents a specific date in YYYY-MM-DD format.
- TBD: make pattern more precise to exclude leading zeros.";
- }
-
- grouping yang-patch {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of a
- YANG Patch edit request message.";
-
- container yang-patch {
- description
- "Represents a conceptual sequence of datastore edits,
- called a patch. Each patch is given a client-assigned
- patch identifier. Each edit MUST be applied
- in ascending order, and all edits MUST be applied.
- If any errors occur, then the target datastore MUST NOT
- be changed by the patch operation.
-
- A patch MUST be validated by the server to be a
- well-formed message before any of the patch edits
- are validated or attempted.
-
- YANG datastore validation (defined in RFC 6020, section
- 8.3.3) is performed after all edits have been
- individually validated.
-
- It is possible for a datastore constraint violation to occur
- due to any node in the datastore, including nodes not
- included in the edit list. Any validation errors MUST
- be reported in the reply message.";
-
- reference
- "RFC 6020, section 8.3.";
-
- leaf patch-id {
- type string;
- description
- "An arbitrary string provided by the client to identify
- the entire patch. This value SHOULD be present in any
- audit logging records generated by the server for the
- patch. Error messages returned by the server pertaining
- to this patch will be identified by this patch-id value.";
- }
-
- leaf comment {
- type string {
- length "0 .. 1024";
- }
- description
- "An arbitrary string provided by the client to describe
- the entire patch. This value SHOULD be present in any
- audit logging records generated by the server for the
- patch.";
- }
-
- list edit {
- key edit-id;
- ordered-by user;
-
- description
- "Represents one edit within the YANG Patch
- request message.";
-
- leaf edit-id {
- type string;
- description
- "Arbitrary string index for the edit.
- Error messages returned by the server pertaining
- to a specific edit will be identified by this
- value.";
- }
-
- leaf operation {
- type enumeration {
- enum create {
- description
- "The target data node is created using the
- supplied value, only if it does not already
- exist.";
- }
- enum delete {
- description
- "Delete the target node, only if the data resource
- currently exists, otherwise return an error.";
- }
- enum insert {
- description
- "Insert the supplied value into a user-ordered
- list or leaf-list entry. The target node must
- represent a new data resource.";
- }
- enum merge {
- description
- "The supplied value is merged with the target data
- node.";
- }
- enum move {
- description
- "Move the target node. Reorder a user-ordered
- list or leaf-list. The target node must represent
- an existing data resource.";
- }
- enum replace {
- description
- "The supplied value is used to replace the target
- data node.";
- }
- enum remove {
- description
- "Delete the target node if it currently exists.";
- }
- }
- mandatory true;
- description
- "The datastore operation requested for the associated
- edit entry";
- }
-
- leaf target {
- type data-resource-identifier;
- mandatory true;
- description
- "Identifies the target data resource for the edit
- operation.";
- }
-
- leaf point {
- when "(../operation = 'insert' or " +
- "../operation = 'move') and " +
- "(../where = 'before' or ../where = 'after')" {
- description
- "Point leaf only applies for insert or move
- operations, before or after an existing entry.";
- }
- type data-resource-identifier;
- description
- "The absolute URL path for the data node that is being
- used as the insertion point or move point for the
- target of this edit entry.";
- }
-
- leaf where {
- when "../operation = 'insert' or ../operation = 'move'" {
- description
- "Where leaf only applies for insert or move
- operations.";
- }
- type enumeration {
- enum before {
- description
- "Insert or move a data node before the data resource
- identified by the 'point' parameter.";
- }
- enum after {
- description
- "Insert or move a data node after the data resource
- identified by the 'point' parameter.";
- }
- enum first {
- description
- "Insert or move a data node so it becomes ordered
- as the first entry.";
- }
- enum last {
- description
- "Insert or move a data node so it becomes ordered
- as the last entry.";
- }
-
- }
- default last;
- description
- "Identifies where a data resource will be inserted or
- moved. YANG only allows these operations for
- list and leaf-list data nodes that are ordered-by
- user.";
- }
-
- anyxml value {
- when "(../operation = 'create' or " +
- "../operation = 'merge' " +
- "or ../operation = 'replace' or " +
- "../operation = 'insert')" {
- description
- "Value node only used for create, merge,
- replace, and insert operations";
- }
- description
- "Value used for this edit operation.";
- }
- }
- }
-
- } // grouping yang-patch
-
-
- grouping yang-patch-status {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of
- YANG Patch status response message.";
-
- container yang-patch-status {
- description
- "A container representing the response message
- sent by the server after a YANG Patch edit
- request message has been processed.";
-
- leaf patch-id {
- type string;
- description
- "The patch-id value used in the request";
- }
-
- choice global-status {
- description
- "Report global errors or complete success.
- If there is no case selected then errors
- are reported in the edit-status container.";
-
- case global-errors {
- uses errors;
- description
- "This container will be present if global
- errors unrelated to a specific edit occurred.";
- }
- leaf ok {
- type empty;
- description
- "This leaf will be present if the request succeeded
- and there are no errors reported in the edit-status
- container.";
- }
- }
-
- container edit-status {
- description
- "This container will be present if there are
- edit-specific status responses to report.";
-
- list edit {
- key edit-id;
-
- description
- "Represents a list of status responses,
- corresponding to edits in the YANG Patch
- request message. If an edit entry was
- skipped or not reached by the server,
- then this list will not contain a corresponding
- entry for that edit.";
-
- leaf edit-id {
- type string;
- description
- "Response status is for the edit list entry
- with this edit-id value.";
- }
- choice edit-status-choice {
- description
- "A choice between different types of status
- responses for each edit entry.";
- leaf ok {
- type empty;
- description
- "This edit entry was invoked without any
- errors detected by the server associated
- with this edit.";
- }
- leaf location {
- type inet:uri;
- description
- "Contains the Location header value that would be
- returned if this edit causes a new resource to be
- created. If the edit identified by the same edit-id
- value was successfully invoked and a new resource
- was created, then this field will be returned
- instead of 'ok'.";
- }
- case errors {
- uses errors;
- description
- "The server detected errors associated with the
- edit identified by the same edit-id value.";
- }
- }
- }
- }
- }
- } // grouping yang-patch-status
-
-
- grouping errors {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of a
- YANG Patch errors report within a response message.";
-
- container errors {
- config false; // needed so list error does not need a key
- description
- "Represents an error report returned by the server if
- a request results in an error.";
-
- list error {
- description
- "An entry containing information about one
- specific error that occurred while processing
- a RESTCONF request.";
- reference "RFC 6241, Section 4.3";
-
- leaf error-type {
- type enumeration {
- enum transport {
- description "The transport layer";
- }
- enum rpc {
- description "The rpc or notification layer";
- }
- enum protocol {
- description "The protocol operation layer";
- }
- enum application {
- description "The server application layer";
- }
- }
- mandatory true;
- description
- "The protocol layer where the error occurred.";
- }
-
- leaf error-tag {
- type string;
- mandatory true;
- description
- "The enumerated error tag.";
- }
-
- leaf error-app-tag {
- type string;
- description
- "The application-specific error tag.";
- }
-
- leaf error-path {
- type data-resource-identifier;
- description
- "The target data resource identifier associated
- with the error, if any.";
- }
-
- leaf error-message {
- type string;
- description
- "A message describing the error.";
- }
-
- container error-info {
- description
- "A container allowing additional information
- to be included in the error report.";
- // arbitrary anyxml content here
- }
- }
- }
- } // grouping errors
-
-
- grouping restconf {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of
- the RESTCONF API resource.";
-
- container restconf {
- description
- "Conceptual container representing the
- application/yang.api resource type.";
-
- container config {
- description
- "Container representing the application/yang.datastore
- resource type. Represents the conceptual root of the
- unified configuration datastore containing YANG data
- nodes. The child nodes of this container are
- configuration data resources (application/yang.data)
- defined as top-level YANG data nodes from the modules
- advertised by the server in /restconf/modules.";
- }
-
- container operational {
- description
- "Container representing the application/yang.datastore
- resource type. Represents the conceptual root of the
- operational data supported by the server. The child
- nodes of this container are operational data resources
- (application/yang.data) defined as top-level
- YANG data nodes from the modules advertised by
- the server in /restconf/modules.";
- }
-
- container modules {
- description
- "Contains a list of module description entries.
- These modules are currently loaded into the server.";
-
- list module {
- key "name revision";
- description
- "Each entry represents one module currently
- supported by the server.";
-
- leaf name {
- type yang:yang-identifier;
- description "The YANG module name.";
- }
- leaf revision {
- type union {
- type revision-identifier;
- type string { length 0; }
- }
- description
- "The YANG module revision date. An empty string is
- used if no revision statement is present in the
- YANG module.";
- }
- leaf namespace {
- type inet:uri;
- mandatory true;
- description
- "The XML namespace identifier for this module.";
- }
- leaf-list feature {
- type yang:yang-identifier;
- description
- "List of YANG feature names from this module that are
- supported by the server.";
- }
- leaf-list deviation {
- type yang:yang-identifier;
- description
- "List of YANG deviation module names used by this
- server to modify the conformance of the module
- associated with this entry.";
- }
- }
- }
-
- container operations {
- description
- "Container for all operation resources
- (application/yang.operation),
-
- Each resource is represented as an empty leaf with the
- name of the RPC operation from the YANG rpc statement.
-
- E.g.;
-
- POST /restconf/operations/show-log-errors
-
- leaf show-log-errors {
- type empty;
- }
- ";
- }
-
- container streams {
- description
- "Container representing the notification event streams
- supported by the server.";
- reference
- "RFC 5277, Section 3.4, <streams> element.";
-
- list stream {
- key name;
- description
- "Each entry describes an event stream supported by
- the server.";
-
- leaf name {
- type string;
- description "The stream name";
- reference "RFC 5277, Section 3.4, <name> element.";
- }
-
- leaf description {
- type string;
- description "Description of stream content";
- reference
- "RFC 5277, Section 3.4, <description> element.";
- }
-
- leaf replay-support {
- type boolean;
- description
- "Indicates if replay buffer supported for this stream";
- reference
- "RFC 5277, Section 3.4, <replaySupport> element.";
- }
-
- leaf replay-log-creation-time {
- type yang:date-and-time;
- description
- "Indicates the time the replay log for this stream
- was created.";
- reference
- "RFC 5277, Section 3.4, <replayLogCreationTime>
- element.";
- }
-
- leaf events {
- type empty;
- description
- "Represents the entry point for establishing
- notification delivery via server sent events.";
- }
- }
- }
-
- leaf version {
- type enumeration {
- enum "1.0" {
- description
- "Version 1.0 of the RESTCONF protocol.";
- }
- }
- config false;
- description
- "Contains the RESTCONF protocol version.";
- }
- }
- } // grouping restconf
-
-
- grouping notification {
- description
- "Contains the notification message wrapper definition.";
-
- container notification {
- description
- "RESTCONF notification message wrapper.";
-
- leaf event-time {
- type yang:date-and-time;
- mandatory true;
- description
- "The time the event was generated by the
- event source.";
- reference
- "RFC 5277, section 4, <eventTime> element.";
- }
-
- /* The YANG-specific notification container is encoded
- * after the 'event-time' element. The format
- * corresponds to the notificationContent element
- * in RFC 5277, section 4. For example:
- *
- * module example-one {
- * ...
- * notification event1 { ... }
- *
- * }
- *
- * Encoded as element 'event1' in the namespace
- * for module 'example-one'.
- */
- }
- } // grouping notification
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2015 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.controller.md.sal.rest.common;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableClassToInstanceMap;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Optional;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.transform.dom.DOMSource;
-import org.opendaylight.controller.sal.rest.impl.test.providers.TestJsonBodyWriter;
-import org.opendaylight.mdsal.dom.api.DOMMountPoint;
-import org.opendaylight.mdsal.dom.api.DOMMountPointService;
-import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.yangtools.util.xml.UntrustedXML;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
-import org.opendaylight.yangtools.yang.model.api.ContainerLike;
-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.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
-import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-public final class TestRestconfUtils {
-
- private static final Logger LOG = LoggerFactory.getLogger(TestRestconfUtils.class);
-
- private TestRestconfUtils() {
- throw new UnsupportedOperationException("Test utility class");
- }
-
- public static ControllerContext newControllerContext(final EffectiveModelContext schemaContext) {
- return newControllerContext(schemaContext, null);
- }
-
- public static ControllerContext newControllerContext(final EffectiveModelContext schemaContext,
- final DOMMountPoint mountInstance) {
- final DOMMountPointService mockMountService = mock(DOMMountPointService.class);
-
- if (mountInstance != null) {
- doReturn(Optional.of(FixedDOMSchemaService.of(() -> schemaContext))).when(mountInstance)
- .getService(eq(DOMSchemaService.class));
- doReturn(Optional.ofNullable(mountInstance)).when(mockMountService).getMountPoint(
- any(YangInstanceIdentifier.class));
- }
-
- DOMSchemaService mockSchemaService = mock(DOMSchemaService.class);
- doReturn(schemaContext).when(mockSchemaService).getGlobalContext();
-
- DOMSchemaService mockDomSchemaService = mock(DOMSchemaService.class);
- doReturn(ImmutableClassToInstanceMap.of()).when(mockDomSchemaService).getExtensions();
-
- return ControllerContext.newInstance(mockSchemaService, mockMountService, mockDomSchemaService);
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- public static EffectiveModelContext loadSchemaContext(final String yangPath,
- final EffectiveModelContext schemaContext) {
- try {
- Preconditions.checkArgument(yangPath != null, "Path can not be null.");
- Preconditions.checkArgument(!yangPath.isEmpty(), "Path can not be empty.");
- if (schemaContext == null) {
- return YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles(yangPath));
- } else {
- throw new UnsupportedOperationException("Unable to add new yang sources to existing schema context.");
- }
- } catch (final Exception e) {
- LOG.error("Yang files at path: " + yangPath + " weren't loaded.", e);
- }
- return schemaContext;
- }
-
- public static NormalizedNodeContext loadNormalizedContextFromJsonFile() {
- throw new AbstractMethodError("Not implemented yet");
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- public static NormalizedNodeContext loadNormalizedContextFromXmlFile(final String pathToInputFile,
- final String uri, final ControllerContext controllerContext) {
- final InstanceIdentifierContext iiContext = controllerContext.toInstanceIdentifier(uri);
- final InputStream inputStream = TestJsonBodyWriter.class.getResourceAsStream(pathToInputFile);
- try {
- final Document doc = UntrustedXML.newDocumentBuilder().parse(inputStream);
- final NormalizedNode nn = parse(iiContext, doc);
- return new NormalizedNodeContext(iiContext, nn);
- } catch (final Exception e) {
- LOG.error("Load xml file " + pathToInputFile + " fail.", e);
- }
- return null;
- }
-
- private static NormalizedNode parse(final InstanceIdentifierContext iiContext, final Document doc)
- throws XMLStreamException, IOException, SAXException, URISyntaxException {
- final SchemaNode schemaNodeContext = iiContext.getSchemaNode();
- final SchemaInferenceStack stack;
- DataSchemaNode schemaNode = null;
- if (schemaNodeContext instanceof RpcDefinition) {
- final var rpc = (RpcDefinition) schemaNodeContext;
- stack = SchemaInferenceStack.of(iiContext.getSchemaContext());
- stack.enterSchemaTree(rpc.getQName());
- if ("input".equalsIgnoreCase(doc.getDocumentElement().getLocalName())) {
- schemaNode = rpc.getInput();
- } else if ("output".equalsIgnoreCase(doc.getDocumentElement().getLocalName())) {
- schemaNode = rpc.getOutput();
- } else {
- throw new IllegalStateException("Unknown Rpc input node");
- }
- stack.enterSchemaTree(schemaNode.getQName());
- } else if (schemaNodeContext instanceof DataSchemaNode) {
- schemaNode = (DataSchemaNode) schemaNodeContext;
- stack = iiContext.inference().toSchemaInferenceStack();
- } else {
- throw new IllegalStateException("Unknow SchemaNode");
- }
-
- final String docRootElm = doc.getDocumentElement().getLocalName();
- final String schemaNodeName = iiContext.getSchemaNode().getQName().getLocalName();
-
- if (!schemaNodeName.equalsIgnoreCase(docRootElm)) {
- for (final DataSchemaNode child : ((DataNodeContainer) schemaNode).getChildNodes()) {
- if (child.getQName().getLocalName().equalsIgnoreCase(docRootElm)) {
- schemaNode = child;
- stack.enterSchemaTree(child.getQName());
- break;
- }
- }
- }
-
- final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
- final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
- final XmlParserStream xmlParser = XmlParserStream.create(writer, stack.toInference());
-
- if (schemaNode instanceof ContainerLike || schemaNode instanceof ListSchemaNode) {
- xmlParser.traverse(new DOMSource(doc.getDocumentElement()));
- return resultHolder.getResult();
- }
- // FIXME : add another DataSchemaNode extensions e.g. LeafSchemaNode
- return null;
- }
-
- public static Collection<File> loadFiles(final String resourceDirectory) throws FileNotFoundException {
- final String path = TestRestconfUtils.class.getResource(resourceDirectory).getPath();
- final File testDir = new File(path);
- final String[] fileList = testDir.list();
- final List<File> testFiles = new ArrayList<>();
- if (fileList == null) {
- throw new FileNotFoundException(resourceDirectory);
- }
- for (final String fileName : fileList) {
- if (new File(testDir, fileName).isDirectory() == false) {
- testFiles.add(new File(testDir, fileName));
- }
- }
- return testFiles;
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.rest.impl;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
-
-public class InstanceIdentifierTypeLeafTest {
-
- @Test
- public void stringToInstanceIdentifierTest() throws Exception {
- final EffectiveModelContext schemaContext =
- YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles("/instanceidentifier"));
- ControllerContext controllerContext = TestRestconfUtils.newControllerContext(schemaContext);
- final InstanceIdentifierContext instanceIdentifier =
- controllerContext.toInstanceIdentifier(
- "/iid-value-module:cont-iid/iid-list/%2Fiid-value-module%3Acont-iid%2Fiid-value-module%3A"
- + "values-iid%5Biid-value-module:value-iid='value'%5D");
- final YangInstanceIdentifier yiD = instanceIdentifier.getInstanceIdentifier();
- assertNotNull(yiD);
- final PathArgument lastPathArgument = yiD.getLastPathArgument();
- assertTrue(lastPathArgument.getNodeType().getNamespace().toString().equals("iid:value:module"));
- assertTrue(lastPathArgument.getNodeType().getLocalName().equals("iid-list"));
-
- final NodeIdentifierWithPredicates list = (NodeIdentifierWithPredicates) lastPathArgument;
- final YangInstanceIdentifier value = (YangInstanceIdentifier) list.getValue(
- QName.create(lastPathArgument.getNodeType(), "iid-leaf"));
- final PathArgument lastPathArgumentOfValue = value.getLastPathArgument();
- assertTrue(lastPathArgumentOfValue.getNodeType().getNamespace().toString().equals("iid:value:module"));
- assertTrue(lastPathArgumentOfValue.getNodeType().getLocalName().equals("values-iid"));
-
- final NodeIdentifierWithPredicates valueList = (NodeIdentifierWithPredicates) lastPathArgumentOfValue;
- final String valueIid = (String) valueList.getValue(
- QName.create(lastPathArgumentOfValue.getNodeType(), "value-iid"));
- assertEquals("value", valueIid);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.controller.sal.rest.impl.test.providers;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.lang.reflect.Field;
-import java.net.URI;
-import java.util.List;
-import java.util.Optional;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedHashMap;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Request;
-import javax.ws.rs.core.UriInfo;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.mdsal.dom.api.DOMMountPoint;
-import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.netconf.sal.rest.api.RestconfConstants;
-import org.opendaylight.netconf.sal.rest.impl.AbstractIdentifierAwareJaxRsProvider;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.restconf.common.patch.PatchContext;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-
-public abstract class AbstractBodyReaderTest {
- private static Field uriField;
- private static Field requestField;
-
- static {
- try {
- uriField = AbstractIdentifierAwareJaxRsProvider.class.getDeclaredField("uriInfo");
- uriField.setAccessible(true);
- requestField = AbstractIdentifierAwareJaxRsProvider.class.getDeclaredField("request");
- requestField.setAccessible(true);
- } catch (NoSuchFieldException e) {
- throw new RuntimeException(e);
- }
- }
-
- protected final ControllerContext controllerContext;
- protected final MediaType mediaType;
-
- protected AbstractBodyReaderTest(final EffectiveModelContext schemaContext, final DOMMountPoint mountInstance) {
- mediaType = getMediaType();
-
- controllerContext = TestRestconfUtils.newControllerContext(schemaContext, mountInstance);
- }
-
- protected abstract MediaType getMediaType();
-
- protected static EffectiveModelContext schemaContextLoader(final String yangPath,
- final EffectiveModelContext schemaContext) {
- return TestRestconfUtils.loadSchemaContext(yangPath, schemaContext);
- }
-
- protected static <T extends AbstractIdentifierAwareJaxRsProvider> void mockBodyReader(
- final String identifier, final T normalizedNodeProvider, final boolean isPost) throws Exception {
- final UriInfo uriInfoMock = mock(UriInfo.class);
- final MultivaluedMap<String, String> pathParm = new MultivaluedHashMap<>(1);
-
- if (!identifier.isEmpty()) {
- pathParm.put(RestconfConstants.IDENTIFIER, List.of(identifier));
- }
-
- when(uriInfoMock.getPathParameters()).thenReturn(pathParm);
- when(uriInfoMock.getPathParameters(false)).thenReturn(pathParm);
- when(uriInfoMock.getPathParameters(true)).thenReturn(pathParm);
- when(uriInfoMock.getAbsolutePath()).thenReturn(URI.create("restconf"));
- uriField.set(normalizedNodeProvider, uriInfoMock);
-
- final Request request = mock(Request.class);
- if (isPost) {
- when(request.getMethod()).thenReturn("POST");
- } else {
- when(request.getMethod()).thenReturn("PUT");
- }
-
- requestField.set(normalizedNodeProvider, request);
- }
-
- protected static void checkMountPointNormalizedNodeContext(final NormalizedNodeContext nnContext) {
- checkNormalizedNodeContext(nnContext);
- assertNotNull(nnContext.getInstanceIdentifierContext().getMountPoint());
- }
-
- protected static void checkNormalizedNodeContext(final NormalizedNodeContext nnContext) {
- assertNotNull(nnContext.getData());
- assertNotNull(nnContext.getInstanceIdentifierContext().getInstanceIdentifier());
- assertNotNull(nnContext.getInstanceIdentifierContext().getSchemaContext());
- assertNotNull(nnContext.getInstanceIdentifierContext().getSchemaNode());
- }
-
- protected static void checkNormalizedNodeContextRpc(final NormalizedNodeContext nnContext) {
- assertNotNull(nnContext.getData());
- assertNull(nnContext.getInstanceIdentifierContext().getInstanceIdentifier());
- assertNotNull(nnContext.getInstanceIdentifierContext().getSchemaContext());
- assertNotNull(nnContext.getInstanceIdentifierContext().getSchemaNode());
- }
-
- protected static void checkPatchContext(final PatchContext patchContext) {
- assertNotNull(patchContext.getData());
- assertNotNull(patchContext.getInstanceIdentifierContext().getInstanceIdentifier());
- assertNotNull(patchContext.getInstanceIdentifierContext().getSchemaContext());
- assertNotNull(patchContext.getInstanceIdentifierContext().getSchemaNode());
- }
-
- protected static void checkPatchContextMountPoint(final PatchContext patchContext) {
- checkPatchContext(patchContext);
- assertNotNull(patchContext.getInstanceIdentifierContext().getMountPoint());
- }
-
- protected static EffectiveModelContext modelContext(final DOMMountPoint mountPoint) {
- return mountPoint.getService(DOMSchemaService.class)
- .flatMap(svc -> Optional.ofNullable(svc.getGlobalContext()))
- .orElse(null);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.controller.sal.rest.impl.test.providers;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.io.InputStream;
-import java.util.Collection;
-import java.util.Optional;
-import java.util.Set;
-import javax.ws.rs.core.MediaType;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.QNameModule;
-import org.opendaylight.yangtools.yang.common.Revision;
-import org.opendaylight.yangtools.yang.common.XMLNamespace;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
-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.Module;
-import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
-
-public class TestJsonBodyReader extends AbstractBodyReaderTest {
-
- private final JsonNormalizedNodeBodyReader jsonBodyReader;
- private static EffectiveModelContext schemaContext;
-
- private static final QNameModule INSTANCE_IDENTIFIER_MODULE_QNAME = QNameModule.create(
- XMLNamespace.of("instance:identifier:module"), Revision.of("2014-01-17"));
-
- public TestJsonBodyReader() {
- super(schemaContext, null);
- jsonBodyReader = new JsonNormalizedNodeBodyReader(controllerContext);
- }
-
- @Override
- protected MediaType getMediaType() {
- return new MediaType(MediaType.APPLICATION_XML, null);
- }
-
- @BeforeClass
- public static void initialization()
- throws Exception {
- final Collection<File> testFiles = TestRestconfUtils.loadFiles("/instanceidentifier/yang");
- testFiles.addAll(TestRestconfUtils.loadFiles("/invoke-rpc"));
- schemaContext = YangParserTestUtils.parseYangFiles(testFiles);
- }
-
- @Test
- public void moduleDataTest() throws Exception {
- final DataSchemaNode dataSchemaNode =
- schemaContext.getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
- final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName());
- final String uri = "instance-identifier-module:cont";
- mockBodyReader(uri, jsonBodyReader, false);
- final InputStream inputStream = TestJsonBodyReader.class
- .getResourceAsStream("/instanceidentifier/json/jsondata.json");
- final NormalizedNodeContext returnValue = jsonBodyReader
- .readFrom(null, null, null, mediaType, null, inputStream);
- checkNormalizedNodeContext(returnValue);
- checkExpectValueNormalizeNodeContext(dataSchemaNode, returnValue, dataII);
- }
-
- @Test
- public void moduleSubContainerDataPutTest() throws Exception {
- final DataSchemaNode dataSchemaNode =
- schemaContext.getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
- final QName cont1QName = QName.create(dataSchemaNode.getQName(), "cont1");
- final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName()).node(cont1QName);
- final DataSchemaNode dataSchemaNodeOnPath = ((DataNodeContainer) dataSchemaNode).getDataChildByName(cont1QName);
- final String uri = "instance-identifier-module:cont/cont1";
- mockBodyReader(uri, jsonBodyReader, false);
- final InputStream inputStream = TestJsonBodyReader.class
- .getResourceAsStream("/instanceidentifier/json/json_sub_container.json");
- final NormalizedNodeContext returnValue = jsonBodyReader
- .readFrom(null, null, null, mediaType, null, inputStream);
- checkNormalizedNodeContext(returnValue);
- checkExpectValueNormalizeNodeContext(dataSchemaNodeOnPath, returnValue, dataII);
- }
-
- @Test
- public void moduleSubContainerDataPostTest() throws Exception {
- final DataSchemaNode dataSchemaNode =
- schemaContext.getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
- final QName cont1QName = QName.create(dataSchemaNode.getQName(), "cont1");
- final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName()).node(cont1QName);
- final String uri = "instance-identifier-module:cont";
- mockBodyReader(uri, jsonBodyReader, true);
- final InputStream inputStream = TestJsonBodyReader.class
- .getResourceAsStream("/instanceidentifier/json/json_sub_container.json");
- final NormalizedNodeContext returnValue = jsonBodyReader
- .readFrom(null, null, null, mediaType, null, inputStream);
- checkNormalizedNodeContext(returnValue);
- checkExpectValueNormalizeNodeContext(dataSchemaNode, returnValue, dataII);
- }
-
- @Test
- public void moduleSubContainerAugmentDataPostTest() throws Exception {
- final DataSchemaNode dataSchemaNode =
- schemaContext.getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
- final Module augmentModule = schemaContext.findModules(XMLNamespace.of("augment:module")).iterator().next();
- final QName contAugmentQName = QName.create(augmentModule.getQNameModule(), "cont-augment");
- final AugmentationIdentifier augII = new AugmentationIdentifier(Set.of(contAugmentQName));
- final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName())
- .node(augII).node(contAugmentQName);
- final String uri = "instance-identifier-module:cont";
- mockBodyReader(uri, jsonBodyReader, true);
- final InputStream inputStream = TestXmlBodyReader.class
- .getResourceAsStream("/instanceidentifier/json/json_augment_container.json");
- final NormalizedNodeContext returnValue = jsonBodyReader
- .readFrom(null, null, null, mediaType, null, inputStream);
- checkNormalizedNodeContext(returnValue);
- checkExpectValueNormalizeNodeContext(dataSchemaNode, returnValue, dataII);
- }
-
- //FIXME: Uncomment this when JsonParserStream works correctly with case augmentation with choice
- //@Test
- public void moduleSubContainerChoiceAugmentDataPostTest() throws Exception {
- final DataSchemaNode dataSchemaNode =
- schemaContext.getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
- final Module augmentModule = schemaContext.findModules(XMLNamespace.of("augment:module")).iterator().next();
- final QName augmentChoice1QName = QName.create(augmentModule.getQNameModule(), "augment-choice1");
- final QName augmentChoice2QName = QName.create(augmentChoice1QName, "augment-choice2");
- final QName containerQName = QName.create(augmentChoice1QName, "case-choice-case-container1");
- final AugmentationIdentifier augChoice1II = new AugmentationIdentifier(Set.of(augmentChoice1QName));
- final AugmentationIdentifier augChoice2II = new AugmentationIdentifier(Set.of(augmentChoice2QName));
- final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName())
- .node(augChoice1II).node(augmentChoice1QName).node(augChoice2II).node(augmentChoice2QName)
- .node(containerQName);
- final String uri = "instance-identifier-module:cont";
- mockBodyReader(uri, jsonBodyReader, true);
- final InputStream inputStream = TestXmlBodyReader.class
- .getResourceAsStream("/instanceidentifier/json/json_augment_choice_container.json");
- final NormalizedNodeContext returnValue = jsonBodyReader
- .readFrom(null, null, null, mediaType, null, inputStream);
- checkNormalizedNodeContext(returnValue);
- checkExpectValueNormalizeNodeContext(dataSchemaNode, returnValue, dataII);
- }
-
- @Test
- public void rpcModuleInputTest() throws Exception {
- final String uri = "invoke-rpc-module:rpc-test";
- mockBodyReader(uri, jsonBodyReader, true);
- final InputStream inputStream = TestJsonBodyReader.class.getResourceAsStream("/invoke-rpc/json/rpc-input.json");
- final NormalizedNodeContext returnValue = jsonBodyReader.readFrom(null, null, null, mediaType, null,
- inputStream);
- checkNormalizedNodeContextRpc(returnValue);
- final ContainerNode inputNode = (ContainerNode) returnValue.getData();
- final YangInstanceIdentifier yangCont = YangInstanceIdentifier.of(
- QName.create(inputNode.getIdentifier().getNodeType(), "cont"));
- final Optional<DataContainerChild> contDataNode = inputNode.findChildByArg(yangCont.getLastPathArgument());
- assertTrue(contDataNode.isPresent());
- assertTrue(contDataNode.get() instanceof ContainerNode);
- final YangInstanceIdentifier yangleaf = YangInstanceIdentifier.of(
- QName.create(inputNode.getIdentifier().getNodeType(), "lf"));
- final Optional<DataContainerChild> leafDataNode = ((ContainerNode) contDataNode.get())
- .findChildByArg(yangleaf.getLastPathArgument());
- assertTrue(leafDataNode.isPresent());
- assertTrue("lf-test".equalsIgnoreCase(leafDataNode.get().body().toString()));
- }
-
- private static void checkExpectValueNormalizeNodeContext(final DataSchemaNode dataSchemaNode,
- final NormalizedNodeContext nnContext, final YangInstanceIdentifier dataNodeIdent) {
- assertEquals(dataSchemaNode, nnContext.getInstanceIdentifierContext().getSchemaNode());
- assertEquals(dataNodeIdent, nnContext.getInstanceIdentifierContext().getInstanceIdentifier());
- assertNotNull(NormalizedNodes.findNode(nnContext.getData(), dataNodeIdent));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.controller.sal.rest.impl.test.providers;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-
-import java.io.File;
-import java.io.InputStream;
-import java.util.Collection;
-import java.util.Optional;
-import javax.ws.rs.core.MediaType;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.mdsal.dom.api.DOMMountPoint;
-import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.QNameModule;
-import org.opendaylight.yangtools.yang.common.Revision;
-import org.opendaylight.yangtools.yang.common.XMLNamespace;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
-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.test.util.YangParserTestUtils;
-
-public class TestJsonBodyReaderMountPoint extends AbstractBodyReaderTest {
-
- private final JsonNormalizedNodeBodyReader jsonBodyReader;
- private static EffectiveModelContext schemaContext;
-
- private static final QNameModule INSTANCE_IDENTIFIER_MODULE_QNAME = QNameModule.create(
- XMLNamespace.of("instance:identifier:module"), Revision.of("2014-01-17"));
-
- public TestJsonBodyReaderMountPoint() throws NoSuchFieldException, SecurityException {
- super(schemaContext, mock(DOMMountPoint.class));
- jsonBodyReader = new JsonNormalizedNodeBodyReader(controllerContext);
- }
-
- @Override
- protected MediaType getMediaType() {
- return new MediaType(MediaType.APPLICATION_XML, null);
- }
-
- @BeforeClass
- public static void initialization() throws Exception {
- final Collection<File> testFiles = TestRestconfUtils.loadFiles("/instanceidentifier/yang");
- testFiles.addAll(TestRestconfUtils.loadFiles("/invoke-rpc"));
- schemaContext = YangParserTestUtils.parseYangFiles(testFiles);
- }
-
- @Test
- public void moduleDataTest() throws Exception {
- final DataSchemaNode dataSchemaNode = schemaContext
- .getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
- final String uri = "instance-identifier-module:cont/yang-ext:mount/instance-identifier-module:cont";
- mockBodyReader(uri, jsonBodyReader, false);
- final InputStream inputStream = TestJsonBodyReaderMountPoint.class
- .getResourceAsStream("/instanceidentifier/json/jsondata.json");
- final NormalizedNodeContext returnValue = jsonBodyReader.readFrom(null,
- null, null, mediaType, null, inputStream);
- checkMountPointNormalizedNodeContext(returnValue);
- checkExpectValueNormalizeNodeContext(dataSchemaNode, returnValue);
- }
-
- @Test
- public void moduleSubContainerDataPutTest() throws Exception {
- final DataSchemaNode dataSchemaNode = schemaContext
- .getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
- final String uri = "instance-identifier-module:cont/yang-ext:mount/instance-identifier-module:cont/cont1";
- mockBodyReader(uri, jsonBodyReader, false);
- final InputStream inputStream = TestJsonBodyReaderMountPoint.class
- .getResourceAsStream("/instanceidentifier/json/json_sub_container.json");
- final NormalizedNodeContext returnValue = jsonBodyReader.readFrom(null,
- null, null, mediaType, null, inputStream);
- checkMountPointNormalizedNodeContext(returnValue);
- checkExpectValueNormalizeNodeContext(dataSchemaNode, returnValue,
- QName.create(dataSchemaNode.getQName(), "cont1"));
- }
-
- @Test
- public void moduleSubContainerDataPostTest() throws Exception {
- final DataSchemaNode dataSchemaNode = schemaContext
- .getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
- final String uri = "instance-identifier-module:cont/yang-ext:mount/instance-identifier-module:cont";
- mockBodyReader(uri, jsonBodyReader, true);
- final InputStream inputStream = TestJsonBodyReaderMountPoint.class
- .getResourceAsStream("/instanceidentifier/json/json_sub_container.json");
- final NormalizedNodeContext returnValue = jsonBodyReader.readFrom(null,
- null, null, mediaType, null, inputStream);
- checkMountPointNormalizedNodeContext(returnValue);
- checkExpectValueNormalizeNodeContext(dataSchemaNode, returnValue);
- }
-
- @Test
- public void rpcModuleInputTest() throws Exception {
- final String uri = "instance-identifier-module:cont/yang-ext:mount/invoke-rpc-module:rpc-test";
- mockBodyReader(uri, jsonBodyReader, true);
- final InputStream inputStream = TestJsonBodyReaderMountPoint.class.getResourceAsStream(
- "/invoke-rpc/json/rpc-input.json");
- final NormalizedNodeContext returnValue = jsonBodyReader.readFrom(null, null, null, mediaType, null,
- inputStream);
- checkNormalizedNodeContextRpc(returnValue);
- final ContainerNode inputNode = (ContainerNode) returnValue.getData();
- final YangInstanceIdentifier yangCont = YangInstanceIdentifier.of(
- QName.create(inputNode.getIdentifier().getNodeType(), "cont"));
- final Optional<DataContainerChild> contDataNode = inputNode.findChildByArg(yangCont.getLastPathArgument());
- assertTrue(contDataNode.isPresent());
- assertTrue(contDataNode.get() instanceof ContainerNode);
- final YangInstanceIdentifier yangleaf = YangInstanceIdentifier.of(
- QName.create(inputNode.getIdentifier().getNodeType(), "lf"));
- final Optional<DataContainerChild> leafDataNode =
- ((ContainerNode) contDataNode.get()).findChildByArg(yangleaf.getLastPathArgument());
- assertTrue(leafDataNode.isPresent());
- assertTrue("lf-test".equalsIgnoreCase(leafDataNode.get().body().toString()));
- }
-
- private void checkExpectValueNormalizeNodeContext(final DataSchemaNode dataSchemaNode,
- final NormalizedNodeContext nnContext) {
- checkExpectValueNormalizeNodeContext(dataSchemaNode, nnContext, null);
- }
-
- protected void checkExpectValueNormalizeNodeContext(final DataSchemaNode dataSchemaNode,
- final NormalizedNodeContext nnContext, final QName qualifiedName) {
- YangInstanceIdentifier dataNodeIdent = YangInstanceIdentifier.of(dataSchemaNode.getQName());
- final DOMMountPoint mountPoint = nnContext.getInstanceIdentifierContext().getMountPoint();
- final DataSchemaNode mountDataSchemaNode = modelContext(mountPoint).getDataChildByName(
- dataSchemaNode.getQName());
- assertNotNull(mountDataSchemaNode);
- if (qualifiedName != null && dataSchemaNode instanceof DataNodeContainer) {
- final DataSchemaNode child = ((DataNodeContainer) dataSchemaNode).getDataChildByName(qualifiedName);
- dataNodeIdent = YangInstanceIdentifier.builder(dataNodeIdent).node(child.getQName()).build();
- assertTrue(nnContext.getInstanceIdentifierContext().getSchemaNode().equals(child));
- } else {
- assertTrue(mountDataSchemaNode.equals(dataSchemaNode));
- }
- assertNotNull(NormalizedNodes.findNode(nnContext.getData(),
- dataNodeIdent));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.controller.sal.rest.impl.test.providers;
-
-import static org.junit.Assert.assertTrue;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Collection;
-import javax.ws.rs.core.MediaType;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeJsonBodyWriter;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
-
-public class TestJsonBodyWriter extends AbstractBodyReaderTest {
-
- private final JsonNormalizedNodeBodyReader jsonBodyReader;
- private final NormalizedNodeJsonBodyWriter jsonBodyWriter;
- private static EffectiveModelContext schemaContext;
-
- public TestJsonBodyWriter() {
- super(schemaContext, null);
- this.jsonBodyWriter = new NormalizedNodeJsonBodyWriter();
- this.jsonBodyReader = new JsonNormalizedNodeBodyReader(controllerContext);
- }
-
- @Override
- protected MediaType getMediaType() {
- return new MediaType(MediaType.APPLICATION_XML, null);
- }
-
- @BeforeClass
- public static void initialization() throws Exception {
- final Collection<File> testFiles = TestRestconfUtils.loadFiles("/instanceidentifier/yang");
- testFiles.addAll(TestRestconfUtils.loadFiles("/invoke-rpc"));
- schemaContext = YangParserTestUtils.parseYangFiles(testFiles);
- }
-
- @Test
- public void rpcModuleInputTest() throws Exception {
- final String uri = "invoke-rpc-module:rpc-test";
- mockBodyReader(uri, this.jsonBodyReader, true);
- final InputStream inputStream = TestJsonBodyWriter.class
- .getResourceAsStream("/invoke-rpc/json/rpc-output.json");
- final NormalizedNodeContext returnValue = this.jsonBodyReader.readFrom(null,
- null, null, this.mediaType, null, inputStream);
- final OutputStream output = new ByteArrayOutputStream();
- this.jsonBodyWriter.writeTo(returnValue, null, null, null, this.mediaType, null,
- output);
- assertTrue(output.toString().contains("lf-test"));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.controller.sal.rest.impl.test.providers;
-
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThrows;
-
-import java.io.InputStream;
-import javax.ws.rs.core.MediaType;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.netconf.sal.rest.impl.JsonToPatchBodyReader;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.patch.PatchContext;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-
-public class TestJsonPatchBodyReader extends AbstractBodyReaderTest {
- private static EffectiveModelContext schemaContext;
-
- private final JsonToPatchBodyReader jsonToPatchBodyReader;
-
- public TestJsonPatchBodyReader() {
- super(schemaContext, null);
- jsonToPatchBodyReader = new JsonToPatchBodyReader(controllerContext);
- }
-
- @BeforeClass
- public static void initialization() {
- schemaContext = schemaContextLoader("/instanceidentifier/yang", schemaContext);
- }
-
- @Override
- protected MediaType getMediaType() {
- return new MediaType(APPLICATION_JSON, null);
- }
-
- @Test
- public void modulePatchDataTest() throws Exception {
- final String uri = "instance-identifier-patch-module:patch-cont/my-list1/leaf1";
- mockBodyReader(uri, jsonToPatchBodyReader, false);
-
- final InputStream inputStream = TestJsonBodyReader.class.getResourceAsStream(
- "/instanceidentifier/json/jsonPATCHdata.json");
-
- final PatchContext returnValue = jsonToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream);
- checkPatchContext(returnValue);
- }
-
- /**
- * Test of successful Patch consisting of create and delete Patch operations.
- */
- @Test
- public void modulePatchCreateAndDeleteTest() throws Exception {
- final String uri = "instance-identifier-patch-module:patch-cont/my-list1/leaf1";
- mockBodyReader(uri, jsonToPatchBodyReader, false);
-
- final InputStream inputStream = TestJsonBodyReader.class.getResourceAsStream(
- "/instanceidentifier/json/jsonPATCHdataCreateAndDelete.json");
-
- final PatchContext returnValue = jsonToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream);
- checkPatchContext(returnValue);
- }
-
- /**
- * Test trying to use Patch create operation which requires value without value. Test should fail with
- * {@link RestconfDocumentedException} with error code 400.
- */
- @Test
- public void modulePatchValueMissingNegativeTest() throws Exception {
- final String uri = "instance-identifier-patch-module:patch-cont/my-list1/leaf1";
- mockBodyReader(uri, jsonToPatchBodyReader, false);
-
- final InputStream inputStream = TestJsonBodyReader.class.getResourceAsStream(
- "/instanceidentifier/json/jsonPATCHdataValueMissing.json");
-
- final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
- () -> jsonToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream));
- assertEquals(ErrorTag.MALFORMED_MESSAGE, ex.getErrors().get(0).getErrorTag());
- }
-
- /**
- * Test trying to use value with Patch delete operation which does not support value. Test should fail with
- * {@link RestconfDocumentedException} with error code 400.
- */
- @Test
- public void modulePatchValueNotSupportedNegativeTest() throws Exception {
- final String uri = "instance-identifier-patch-module:patch-cont/my-list1/leaf1";
- mockBodyReader(uri, jsonToPatchBodyReader, false);
-
- final InputStream inputStream = TestJsonBodyReader.class.getResourceAsStream(
- "/instanceidentifier/json/jsonPATCHdataValueNotSupported.json");
-
- final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
- () -> jsonToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream));
- assertEquals(ErrorTag.MALFORMED_MESSAGE, ex.getErrors().get(0).getErrorTag());
- }
-
- /**
- * Test using Patch when target is completely specified in request URI and thus target leaf contains only '/' sign.
- */
- @Test
- public void modulePatchCompleteTargetInURITest() throws Exception {
- final String uri = "instance-identifier-patch-module:patch-cont";
- mockBodyReader(uri, jsonToPatchBodyReader, false);
-
- final InputStream inputStream = TestJsonBodyReader.class.getResourceAsStream(
- "/instanceidentifier/json/jsonPATCHdataCompleteTargetInURI.json");
-
- final PatchContext returnValue = jsonToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream);
- checkPatchContext(returnValue);
- }
-
- /**
- * Test of Yang Patch merge operation on list. Test consists of two edit operations - replace and merge.
- */
- @Test
- public void modulePatchMergeOperationOnListTest() throws Exception {
- final String uri = "instance-identifier-patch-module:patch-cont/my-list1/leaf1";
- mockBodyReader(uri, jsonToPatchBodyReader, false);
-
- final InputStream inputStream = TestJsonBodyReader.class
- .getResourceAsStream("/instanceidentifier/json/jsonPATCHMergeOperationOnList.json");
-
- final PatchContext returnValue = jsonToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream);
- checkPatchContext(returnValue);
- }
-
- /**
- * Test of Yang Patch merge operation on container. Test consists of two edit operations - create and merge.
- */
- @Test
- public void modulePatchMergeOperationOnContainerTest() throws Exception {
- final String uri = "instance-identifier-patch-module:patch-cont";
- mockBodyReader(uri, jsonToPatchBodyReader, false);
-
- final InputStream inputStream = TestJsonBodyReader.class.getResourceAsStream(
- "/instanceidentifier/json/jsonPATCHMergeOperationOnContainer.json");
-
- final PatchContext returnValue = jsonToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream);
- checkPatchContext(returnValue);
- }
-
- /**
- * Test reading simple leaf value.
- */
- @Test
- public void modulePatchSimpleLeafValueTest() throws Exception {
- final String uri = "instance-identifier-patch-module:patch-cont/my-list1/leaf1";
- mockBodyReader(uri, jsonToPatchBodyReader, false);
-
- final InputStream inputStream = TestJsonBodyReader.class
- .getResourceAsStream("/instanceidentifier/json/jsonPATCHSimpleLeafValue.json");
-
- final PatchContext returnValue = jsonToPatchBodyReader
- .readFrom(null, null, null, mediaType, null, inputStream);
- checkPatchContext(returnValue);
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.rest.impl.test.providers;
-
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThrows;
-import static org.mockito.Mockito.mock;
-
-import java.io.InputStream;
-import javax.ws.rs.core.MediaType;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.mdsal.dom.api.DOMMountPoint;
-import org.opendaylight.netconf.sal.rest.impl.JsonToPatchBodyReader;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.patch.PatchContext;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-
-public class TestJsonPatchBodyReaderMountPoint extends AbstractBodyReaderTest {
- private final JsonToPatchBodyReader jsonToPatchBodyReader;
- private static EffectiveModelContext schemaContext;
- private static final String MOUNT_POINT = "instance-identifier-module:cont/yang-ext:mount";
-
- public TestJsonPatchBodyReaderMountPoint() {
- super(schemaContext, mock(DOMMountPoint.class));
- jsonToPatchBodyReader = new JsonToPatchBodyReader(controllerContext);
- }
-
- @Override
- protected MediaType getMediaType() {
- return new MediaType(APPLICATION_JSON, null);
- }
-
- @BeforeClass
- public static void initialization() {
- schemaContext = schemaContextLoader("/instanceidentifier/yang", schemaContext);
- }
-
- @Test
- public void modulePatchDataTest() throws Exception {
- final String uri = MOUNT_POINT + "/instance-identifier-patch-module:patch-cont/my-list1/leaf1";
- mockBodyReader(uri, jsonToPatchBodyReader, false);
-
- final InputStream inputStream = TestJsonBodyReader.class
- .getResourceAsStream("/instanceidentifier/json/jsonPATCHdata.json");
-
- final PatchContext returnValue = jsonToPatchBodyReader
- .readFrom(null, null, null, mediaType, null, inputStream);
- checkPatchContextMountPoint(returnValue);
- }
-
- /**
- * Test of successful Patch consisting of create and delete Patch operations.
- */
- @Test
- public void modulePatchCreateAndDeleteTest() throws Exception {
- final String uri = MOUNT_POINT + "/instance-identifier-patch-module:patch-cont/my-list1/leaf1";
- mockBodyReader(uri, jsonToPatchBodyReader, false);
-
- final InputStream inputStream = TestJsonBodyReader.class
- .getResourceAsStream("/instanceidentifier/json/jsonPATCHdataCreateAndDelete.json");
-
- final PatchContext returnValue = jsonToPatchBodyReader
- .readFrom(null, null, null, mediaType, null, inputStream);
- checkPatchContextMountPoint(returnValue);
- }
-
- /**
- * Test trying to use Patch create operation which requires value without value. Test should fail with
- * {@link RestconfDocumentedException} with error code 400.
- */
- @Test
- public void modulePatchValueMissingNegativeTest() throws Exception {
- final String uri = MOUNT_POINT + "/instance-identifier-patch-module:patch-cont/my-list1/leaf1";
- mockBodyReader(uri, jsonToPatchBodyReader, false);
-
- final InputStream inputStream = TestJsonBodyReader.class.getResourceAsStream(
- "/instanceidentifier/json/jsonPATCHdataValueMissing.json");
-
- final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
- () -> jsonToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream));
- assertEquals(ErrorTag.MALFORMED_MESSAGE, ex.getErrors().get(0).getErrorTag());
- }
-
- /**
- * Test trying to use value with Patch delete operation which does not support value. Test should fail with
- * {@link RestconfDocumentedException} with error code 400.
- */
- @Test
- public void modulePatchValueNotSupportedNegativeTest() throws Exception {
- final String uri = MOUNT_POINT + "/instance-identifier-patch-module:patch-cont/my-list1/leaf1";
- mockBodyReader(uri, jsonToPatchBodyReader, false);
-
- final InputStream inputStream = TestJsonBodyReader.class
- .getResourceAsStream("/instanceidentifier/json/jsonPATCHdataValueNotSupported.json");
-
- final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
- () -> jsonToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream));
- assertEquals(ErrorTag.MALFORMED_MESSAGE, ex.getErrors().get(0).getErrorTag());
- }
-
- /**
- * Test using Patch when target is completely specified in request URI and thus target leaf contains only '/' sign.
- */
- @Test
- public void modulePatchCompleteTargetInURITest() throws Exception {
- final String uri = MOUNT_POINT + "/instance-identifier-patch-module:patch-cont";
- mockBodyReader(uri, jsonToPatchBodyReader, false);
-
- final InputStream inputStream = TestJsonBodyReader.class
- .getResourceAsStream("/instanceidentifier/json/jsonPATCHdataCompleteTargetInURI.json");
-
- final PatchContext returnValue = jsonToPatchBodyReader
- .readFrom(null, null, null, mediaType, null, inputStream);
- checkPatchContextMountPoint(returnValue);
- }
-
- /**
- * Test of Yang Patch merge operation on list. Test consists of two edit operations - replace and merge.
- */
- @Test
- public void modulePatchMergeOperationOnListTest() throws Exception {
- final String uri = MOUNT_POINT + "/instance-identifier-patch-module:patch-cont/my-list1/leaf1";
- mockBodyReader(uri, jsonToPatchBodyReader, false);
-
- final InputStream inputStream = TestJsonBodyReader.class
- .getResourceAsStream("/instanceidentifier/json/jsonPATCHMergeOperationOnList.json");
-
- final PatchContext returnValue = jsonToPatchBodyReader
- .readFrom(null, null, null, mediaType, null, inputStream);
- checkPatchContextMountPoint(returnValue);
- }
-
- /**
- * Test of Yang Patch merge operation on container. Test consists of two edit operations - create and merge.
- */
- @Test
- public void modulePatchMergeOperationOnContainerTest() throws Exception {
- final String uri = MOUNT_POINT + "/instance-identifier-patch-module:patch-cont";
- mockBodyReader(uri, jsonToPatchBodyReader, false);
-
- final InputStream inputStream = TestJsonBodyReader.class
- .getResourceAsStream("/instanceidentifier/json/jsonPATCHMergeOperationOnContainer.json");
-
- final PatchContext returnValue = jsonToPatchBodyReader
- .readFrom(null, null, null, mediaType, null, inputStream);
- checkPatchContextMountPoint(returnValue);
- }
-
- /**
- * Test reading simple leaf value.
- */
- @Test
- public void modulePatchSimpleLeafValueTest() throws Exception {
- final String uri = MOUNT_POINT + "/instance-identifier-patch-module:patch-cont/my-list1/leaf1";
- mockBodyReader(uri, jsonToPatchBodyReader, false);
-
- final InputStream inputStream = TestJsonBodyReader.class
- .getResourceAsStream("/instanceidentifier/json/jsonPATCHSimpleLeafValue.json");
-
- final PatchContext returnValue = jsonToPatchBodyReader
- .readFrom(null, null, null, mediaType, null, inputStream);
- checkPatchContext(returnValue);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.controller.sal.rest.impl.test.providers;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.File;
-import java.io.InputStream;
-import java.util.Collection;
-import java.util.Optional;
-import java.util.Set;
-import javax.ws.rs.core.MediaType;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.rest.impl.XmlNormalizedNodeBodyReader;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.errors.RestconfError;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.common.ErrorType;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.QNameModule;
-import org.opendaylight.yangtools.yang.common.Revision;
-import org.opendaylight.yangtools.yang.common.XMLNamespace;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
-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.Module;
-import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
-
-public class TestXmlBodyReader extends AbstractBodyReaderTest {
-
- private final XmlNormalizedNodeBodyReader xmlBodyReader;
- private static EffectiveModelContext schemaContext;
- private static final QNameModule INSTANCE_IDENTIFIER_MODULE_QNAME = QNameModule.create(
- XMLNamespace.of("instance:identifier:module"), Revision.of("2014-01-17"));
-
- public TestXmlBodyReader() {
- super(schemaContext, null);
- xmlBodyReader = new XmlNormalizedNodeBodyReader(controllerContext);
- }
-
- @Override
- protected MediaType getMediaType() {
- return new MediaType(MediaType.APPLICATION_XML, null);
- }
-
- @BeforeClass
- public static void initialization() throws Exception {
- final Collection<File> testFiles = TestRestconfUtils.loadFiles("/instanceidentifier/yang");
- testFiles.addAll(TestRestconfUtils.loadFiles("/invoke-rpc"));
- testFiles.addAll(TestRestconfUtils.loadFiles("/foo-xml-test/yang"));
- schemaContext = YangParserTestUtils.parseYangFiles(testFiles);
- }
-
- @Test
- public void putXmlTest() throws Exception {
- runXmlTest(false, "foo:top-level-list/key-value");
- }
-
- @Test
- public void postXmlTest() throws Exception {
- runXmlTest(true, "");
- }
-
- private void runXmlTest(final boolean isPost, final String path) throws Exception {
- mockBodyReader(path, xmlBodyReader, isPost);
- final InputStream inputStream = TestXmlBodyReader.class.getResourceAsStream("/foo-xml-test/foo.xml");
- final NormalizedNodeContext nnc = xmlBodyReader.readFrom(null, null, null, mediaType, null, inputStream);
- assertNotNull(nnc);
-
- assertTrue(nnc.getData() instanceof MapEntryNode);
- final MapEntryNode data = (MapEntryNode) nnc.getData();
- assertEquals(2, data.size());
- for (final DataContainerChild child : data.body()) {
- switch (child.getIdentifier().getNodeType().getLocalName()) {
- case "key-leaf":
- assertEquals("key-value", child.body());
- break;
-
- case "ordinary-leaf":
- assertEquals("leaf-value", child.body());
- break;
- default:
- fail();
- }
- }
- }
-
- @Test
- public void moduleDataTest() throws Exception {
- final DataSchemaNode dataSchemaNode =
- schemaContext.getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
- final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName());
- final String uri = "instance-identifier-module:cont";
- mockBodyReader(uri, xmlBodyReader, false);
- final InputStream inputStream = TestXmlBodyReader.class
- .getResourceAsStream("/instanceidentifier/xml/xmldata.xml");
- final NormalizedNodeContext returnValue = xmlBodyReader
- .readFrom(null, null, null, mediaType, null, inputStream);
- checkNormalizedNodeContext(returnValue);
- checkExpectValueNormalizeNodeContext(dataSchemaNode, returnValue, dataII);
- }
-
- @Test
- public void moduleSubContainerDataPutTest() throws Exception {
- final DataSchemaNode dataSchemaNode =
- schemaContext.getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
- final QName cont1QName = QName.create(dataSchemaNode.getQName(), "cont1");
- final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName()).node(cont1QName);
- final DataSchemaNode dataSchemaNodeOnPath = ((DataNodeContainer) dataSchemaNode).getDataChildByName(cont1QName);
- final String uri = "instance-identifier-module:cont/cont1";
- mockBodyReader(uri, xmlBodyReader, false);
- final InputStream inputStream = TestXmlBodyReader.class
- .getResourceAsStream("/instanceidentifier/xml/xml_sub_container.xml");
- final NormalizedNodeContext returnValue = xmlBodyReader
- .readFrom(null, null, null, mediaType, null, inputStream);
- checkNormalizedNodeContext(returnValue);
- checkExpectValueNormalizeNodeContext(dataSchemaNodeOnPath, returnValue, dataII);
- }
-
- @Test
- public void moduleSubContainerDataPostTest() throws Exception {
- final DataSchemaNode dataSchemaNode =
- schemaContext.getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
- final QName cont1QName = QName.create(dataSchemaNode.getQName(), "cont1");
- final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName()).node(cont1QName);
- final String uri = "instance-identifier-module:cont";
- mockBodyReader(uri, xmlBodyReader, true);
- final InputStream inputStream = TestXmlBodyReader.class
- .getResourceAsStream("/instanceidentifier/xml/xml_sub_container.xml");
- final NormalizedNodeContext returnValue = xmlBodyReader
- .readFrom(null, null, null, mediaType, null, inputStream);
- checkNormalizedNodeContext(returnValue);
- checkExpectValueNormalizeNodeContext(dataSchemaNode, returnValue, dataII);
- }
-
- @Test
- public void moduleSubContainerAugmentDataPostTest() throws Exception {
- final DataSchemaNode dataSchemaNode =
- schemaContext.getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
- final Module augmentModule = schemaContext.findModules(XMLNamespace.of("augment:module")).iterator().next();
- final QName contAugmentQName = QName.create(augmentModule.getQNameModule(), "cont-augment");
- final AugmentationIdentifier augII = new AugmentationIdentifier(Set.of(contAugmentQName));
- final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName())
- .node(augII).node(contAugmentQName);
- final String uri = "instance-identifier-module:cont";
- mockBodyReader(uri, xmlBodyReader, true);
- final InputStream inputStream = TestXmlBodyReader.class
- .getResourceAsStream("/instanceidentifier/xml/xml_augment_container.xml");
- final NormalizedNodeContext returnValue = xmlBodyReader
- .readFrom(null, null, null, mediaType, null, inputStream);
- checkNormalizedNodeContext(returnValue);
- checkExpectValueNormalizeNodeContext(dataSchemaNode, returnValue, dataII);
- }
-
- @Test
- public void moduleSubContainerChoiceAugmentDataPostTest() throws Exception {
- final DataSchemaNode dataSchemaNode =
- schemaContext.getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
- final Module augmentModule = schemaContext.findModules(XMLNamespace.of("augment:module")).iterator().next();
- final QName augmentChoice1QName = QName.create(augmentModule.getQNameModule(), "augment-choice1");
- final QName augmentChoice2QName = QName.create(augmentChoice1QName, "augment-choice2");
- final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName())
- .node(new AugmentationIdentifier(Set.of(augmentChoice1QName)))
- .node(augmentChoice1QName)
- // FIXME: DataSchemaTreeNode intepretation seems to have a bug
- //.node(new AugmentationIdentifier(Set.of(augmentChoice2QName)))
- .node(augmentChoice2QName)
- .node(QName.create(augmentChoice1QName, "case-choice-case-container1"));
- final String uri = "instance-identifier-module:cont";
- mockBodyReader(uri, xmlBodyReader, true);
- final InputStream inputStream = TestXmlBodyReader.class
- .getResourceAsStream("/instanceidentifier/xml/xml_augment_choice_container.xml");
- final NormalizedNodeContext returnValue = xmlBodyReader
- .readFrom(null, null, null, mediaType, null, inputStream);
- checkNormalizedNodeContext(returnValue);
- checkExpectValueNormalizeNodeContext(dataSchemaNode, returnValue, dataII);
- }
-
- @Test
- public void rpcModuleInputTest() throws Exception {
- final String uri = "invoke-rpc-module:rpc-test";
- mockBodyReader(uri, xmlBodyReader, true);
- final InputStream inputStream = TestXmlBodyReader.class.getResourceAsStream("/invoke-rpc/xml/rpc-input.xml");
- final NormalizedNodeContext returnValue = xmlBodyReader.readFrom(null, null, null, mediaType, null,
- inputStream);
- checkNormalizedNodeContextRpc(returnValue);
- final ContainerNode contNode = (ContainerNode) returnValue.getData();
- final Optional<DataContainerChild> contDataNodePotential = contNode.findChildByArg(new NodeIdentifier(
- QName.create(contNode.getIdentifier().getNodeType(), "cont")));
- assertTrue(contDataNodePotential.isPresent());
- final ContainerNode contDataNode = (ContainerNode) contDataNodePotential.get();
- final Optional<DataContainerChild> leafDataNode = contDataNode.findChildByArg(new NodeIdentifier(
- QName.create(contDataNode.getIdentifier().getNodeType(), "lf")));
- assertTrue(leafDataNode.isPresent());
- assertTrue("lf-test".equalsIgnoreCase(leafDataNode.get().body().toString()));
- }
-
- private static void checkExpectValueNormalizeNodeContext(final DataSchemaNode dataSchemaNode,
- final NormalizedNodeContext nnContext, final YangInstanceIdentifier dataNodeIdent) {
- assertEquals(dataSchemaNode, nnContext.getInstanceIdentifierContext().getSchemaNode());
- assertEquals(dataNodeIdent, nnContext.getInstanceIdentifierContext().getInstanceIdentifier());
- assertNotNull(NormalizedNodes.findNode(nnContext.getData(), dataNodeIdent));
- }
-
- /**
- * Test when container with the same name is placed in two modules (foo-module and bar-module). Namespace must be
- * used to distinguish between them to find correct one. Check if container was found not only according to its name
- * but also by correct namespace used in payload.
- */
- @Test
- public void findFooContainerUsingNamespaceTest() throws Exception {
- mockBodyReader("", xmlBodyReader, true);
- final InputStream inputStream = TestXmlBodyReader.class
- .getResourceAsStream("/instanceidentifier/xml/xmlDataFindFooContainer.xml");
- final NormalizedNodeContext returnValue = xmlBodyReader
- .readFrom(null, null, null, mediaType, null, inputStream);
-
- // check return value
- checkNormalizedNodeContext(returnValue);
- // check if container was found both according to its name and namespace
- assertEquals("Not correct container found, name was ignored",
- "foo-bar-container", returnValue.getData().getIdentifier().getNodeType().getLocalName());
- assertEquals("Not correct container found, namespace was ignored",
- "foo:module", returnValue.getData().getIdentifier().getNodeType().getNamespace().toString());
- }
-
- /**
- * Test when container with the same name is placed in two modules (foo-module and bar-module). Namespace must be
- * used to distinguish between them to find correct one. Check if container was found not only according to its name
- * but also by correct namespace used in payload.
- */
- @Test
- public void findBarContainerUsingNamespaceTest() throws Exception {
- mockBodyReader("", xmlBodyReader, true);
- final InputStream inputStream = TestXmlBodyReader.class
- .getResourceAsStream("/instanceidentifier/xml/xmlDataFindBarContainer.xml");
- final NormalizedNodeContext returnValue = xmlBodyReader
- .readFrom(null, null, null, mediaType, null, inputStream);
-
- // check return value
- checkNormalizedNodeContext(returnValue);
- // check if container was found both according to its name and namespace
- assertEquals("Not correct container found, name was ignored",
- "foo-bar-container", returnValue.getData().getIdentifier().getNodeType().getLocalName());
- assertEquals("Not correct container found, namespace was ignored",
- "bar:module", returnValue.getData().getIdentifier().getNodeType().getNamespace().toString());
- }
-
- /**
- * Test PUT operation when message root element is not the same as the last element in request URI.
- * PUT operation message should always start with schema node from URI otherwise exception should be
- * thrown.
- */
- @Test
- public void wrongRootElementTest() throws Exception {
- mockBodyReader("instance-identifier-module:cont", xmlBodyReader, false);
- final InputStream inputStream = TestXmlBodyReader.class.getResourceAsStream(
- "/instanceidentifier/xml/bug7933.xml");
- try {
- xmlBodyReader.readFrom(null, null, null, mediaType, null, inputStream);
- Assert.fail("Test should fail due to malformed PUT operation message");
- } catch (final RestconfDocumentedException exception) {
- final RestconfError restconfError = exception.getErrors().get(0);
- assertEquals(ErrorType.PROTOCOL, restconfError.getErrorType());
- assertEquals(ErrorTag.MALFORMED_MESSAGE, restconfError.getErrorTag());
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.controller.sal.rest.impl.test.providers;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-
-import java.io.File;
-import java.io.InputStream;
-import java.util.Collection;
-import java.util.Optional;
-import javax.ws.rs.core.MediaType;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.mdsal.dom.api.DOMMountPoint;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.rest.impl.XmlNormalizedNodeBodyReader;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.errors.RestconfError;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.common.ErrorType;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.QNameModule;
-import org.opendaylight.yangtools.yang.common.Revision;
-import org.opendaylight.yangtools.yang.common.XMLNamespace;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
-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.test.util.YangParserTestUtils;
-
-public class TestXmlBodyReaderMountPoint extends AbstractBodyReaderTest {
- private final XmlNormalizedNodeBodyReader xmlBodyReader;
- private static EffectiveModelContext schemaContext;
-
- private static final QNameModule INSTANCE_IDENTIFIER_MODULE_QNAME = QNameModule.create(
- XMLNamespace.of("instance:identifier:module"), Revision.of("2014-01-17"));
-
- public TestXmlBodyReaderMountPoint() {
- super(schemaContext, mock(DOMMountPoint.class));
- xmlBodyReader = new XmlNormalizedNodeBodyReader(controllerContext);
- }
-
- @Override
- protected MediaType getMediaType() {
- return new MediaType(MediaType.APPLICATION_XML, null);
- }
-
- @BeforeClass
- public static void initialization() throws Exception {
- final Collection<File> testFiles = TestRestconfUtils.loadFiles("/instanceidentifier/yang");
- testFiles.addAll(TestRestconfUtils.loadFiles("/invoke-rpc"));
- schemaContext = YangParserTestUtils.parseYangFiles(testFiles);
- }
-
- @Test
- public void moduleDataTest() throws Exception {
- final DataSchemaNode dataSchemaNode = schemaContext
- .getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
- final String uri = "instance-identifier-module:cont/yang-ext:mount/instance-identifier-module:cont";
- mockBodyReader(uri, xmlBodyReader, false);
- final InputStream inputStream = TestXmlBodyReaderMountPoint.class
- .getResourceAsStream("/instanceidentifier/xml/xmldata.xml");
- final NormalizedNodeContext returnValue = xmlBodyReader.readFrom(null,
- null, null, mediaType, null, inputStream);
- checkMountPointNormalizedNodeContext(returnValue);
- checkExpectValueNormalizeNodeContext(dataSchemaNode, returnValue);
- }
-
- @Test
- public void moduleSubContainerDataPutTest() throws Exception {
- final DataSchemaNode dataSchemaNode = schemaContext
- .getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
- final String uri = "instance-identifier-module:cont/yang-ext:mount/instance-identifier-module:cont/cont1";
- mockBodyReader(uri, xmlBodyReader, false);
- final InputStream inputStream = TestXmlBodyReaderMountPoint.class
- .getResourceAsStream("/instanceidentifier/xml/xml_sub_container.xml");
- final NormalizedNodeContext returnValue = xmlBodyReader.readFrom(null,
- null, null, mediaType, null, inputStream);
- checkMountPointNormalizedNodeContext(returnValue);
- checkExpectValueNormalizeNodeContext(dataSchemaNode, returnValue,
- QName.create(dataSchemaNode.getQName(), "cont1"));
- }
-
- @Test
- public void moduleSubContainerDataPostTest() throws Exception {
- final DataSchemaNode dataSchemaNode = schemaContext
- .getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
- final String uri = "instance-identifier-module:cont/yang-ext:mount/instance-identifier-module:cont";
- mockBodyReader(uri, xmlBodyReader, true);
- final InputStream inputStream = TestXmlBodyReaderMountPoint.class
- .getResourceAsStream("/instanceidentifier/xml/xml_sub_container.xml");
- final NormalizedNodeContext returnValue = xmlBodyReader.readFrom(null,
- null, null, mediaType, null, inputStream);
- checkMountPointNormalizedNodeContext(returnValue);
- checkExpectValueNormalizeNodeContext(dataSchemaNode, returnValue);
- }
-
- @Test
- public void rpcModuleInputTest() throws Exception {
- final String uri = "instance-identifier-module:cont/yang-ext:mount/invoke-rpc-module:rpc-test";
- mockBodyReader(uri, xmlBodyReader, true);
- final InputStream inputStream = TestXmlBodyReaderMountPoint.class
- .getResourceAsStream("/invoke-rpc/xml/rpc-input.xml");
- final NormalizedNodeContext returnValue = xmlBodyReader.readFrom(null,
- null, null, mediaType, null, inputStream);
- checkNormalizedNodeContextRpc(returnValue);
- final ContainerNode contNode = (ContainerNode) returnValue.getData();
- final YangInstanceIdentifier yangCont = YangInstanceIdentifier.of(
- QName.create(contNode.getIdentifier().getNodeType(), "cont"));
- final Optional<DataContainerChild> contDataNodePotential =
- contNode.findChildByArg(yangCont.getLastPathArgument());
- assertTrue(contDataNodePotential.isPresent());
- final ContainerNode contDataNode = (ContainerNode) contDataNodePotential.get();
- final YangInstanceIdentifier yangLeaf = YangInstanceIdentifier.of(
- QName.create(contDataNode.getIdentifier().getNodeType(), "lf"));
- final Optional<DataContainerChild> leafDataNode = contDataNode.findChildByArg(yangLeaf.getLastPathArgument());
- assertTrue(leafDataNode.isPresent());
- assertTrue("lf-test".equalsIgnoreCase(leafDataNode.get().body().toString()));
- }
-
- private void checkExpectValueNormalizeNodeContext(
- final DataSchemaNode dataSchemaNode,
- final NormalizedNodeContext nnContext) {
- checkExpectValueNormalizeNodeContext(dataSchemaNode, nnContext, null);
- }
-
- protected void checkExpectValueNormalizeNodeContext(
- final DataSchemaNode dataSchemaNode, final NormalizedNodeContext nnContext, final QName qualifiedName) {
- YangInstanceIdentifier dataNodeIdent = YangInstanceIdentifier.of(dataSchemaNode.getQName());
- final DOMMountPoint mountPoint = nnContext.getInstanceIdentifierContext().getMountPoint();
- final DataSchemaNode mountDataSchemaNode =
- modelContext(mountPoint).getDataChildByName(dataSchemaNode.getQName());
- assertNotNull(mountDataSchemaNode);
- if (qualifiedName != null && dataSchemaNode instanceof DataNodeContainer) {
- final DataSchemaNode child = ((DataNodeContainer) dataSchemaNode).getDataChildByName(qualifiedName);
- dataNodeIdent = YangInstanceIdentifier.builder(dataNodeIdent).node(child.getQName()).build();
- assertTrue(nnContext.getInstanceIdentifierContext().getSchemaNode().equals(child));
- } else {
- assertTrue(mountDataSchemaNode.equals(dataSchemaNode));
- }
- assertNotNull(NormalizedNodes.findNode(nnContext.getData(), dataNodeIdent));
- }
-
- /**
- * Test when container with the same name is placed in two modules (foo-module and bar-module). Namespace must be
- * used to distinguish between them to find correct one. Check if container was found not only according to its name
- * but also by correct namespace used in payload.
- */
- @Test
- public void findFooContainerUsingNamespaceTest() throws Exception {
- mockBodyReader("instance-identifier-module:cont/yang-ext:mount", xmlBodyReader, true);
- final InputStream inputStream = TestXmlBodyReader.class
- .getResourceAsStream("/instanceidentifier/xml/xmlDataFindFooContainer.xml");
- final NormalizedNodeContext returnValue = xmlBodyReader
- .readFrom(null, null, null, mediaType, null, inputStream);
-
- // check return value
- checkMountPointNormalizedNodeContext(returnValue);
- // check if container was found both according to its name and namespace
- assertEquals("Not correct container found, name was ignored",
- "foo-bar-container", returnValue.getData().getIdentifier().getNodeType().getLocalName());
- assertEquals("Not correct container found, namespace was ignored",
- "foo:module", returnValue.getData().getIdentifier().getNodeType().getNamespace().toString());
- }
-
- /**
- * Test when container with the same name is placed in two modules (foo-module and bar-module). Namespace must be
- * used to distinguish between them to find correct one. Check if container was found not only according to its name
- * but also by correct namespace used in payload.
- */
- @Test
- public void findBarContainerUsingNamespaceTest() throws Exception {
- mockBodyReader("instance-identifier-module:cont/yang-ext:mount", xmlBodyReader, true);
- final InputStream inputStream = TestXmlBodyReader.class
- .getResourceAsStream("/instanceidentifier/xml/xmlDataFindBarContainer.xml");
- final NormalizedNodeContext returnValue = xmlBodyReader
- .readFrom(null, null, null, mediaType, null, inputStream);
-
- // check return value
- checkMountPointNormalizedNodeContext(returnValue);
- // check if container was found both according to its name and namespace
- assertEquals("Not correct container found, name was ignored",
- "foo-bar-container", returnValue.getData().getIdentifier().getNodeType().getLocalName());
- assertEquals("Not correct container found, namespace was ignored",
- "bar:module", returnValue.getData().getIdentifier().getNodeType().getNamespace().toString());
- }
-
- /**
- * Test PUT operation when message root element is not the same as the last element in request URI.
- * PUT operation message should always start with schema node from URI otherwise exception should be
- * thrown.
- */
- @Test
- public void wrongRootElementTest() throws Exception {
- mockBodyReader("instance-identifier-module:cont/yang-ext:mount", xmlBodyReader, false);
- final InputStream inputStream = TestXmlBodyReader.class.getResourceAsStream(
- "/instanceidentifier/xml/bug7933.xml");
- try {
- xmlBodyReader.readFrom(null, null, null, mediaType, null, inputStream);
- Assert.fail("Test should fail due to malformed PUT operation message");
- } catch (final RestconfDocumentedException exception) {
- final RestconfError restconfError = exception.getErrors().get(0);
- assertEquals(ErrorType.PROTOCOL, restconfError.getErrorType());
- assertEquals(ErrorTag.MALFORMED_MESSAGE, restconfError.getErrorTag());
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.controller.sal.rest.impl.test.providers;
-
-import static org.junit.Assert.assertTrue;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.OutputStream;
-import java.util.Collection;
-import javax.ws.rs.core.MediaType;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeXmlBodyWriter;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
-
-public class TestXmlBodyWriter extends AbstractBodyReaderTest {
-
- private final NormalizedNodeXmlBodyWriter xmlBodyWriter;
- private static EffectiveModelContext schemaContext;
-
- public TestXmlBodyWriter() {
- super(schemaContext, null);
- this.xmlBodyWriter = new NormalizedNodeXmlBodyWriter();
- }
-
- @Override
- protected MediaType getMediaType() {
- return new MediaType(MediaType.APPLICATION_XML, null);
- }
-
- @BeforeClass
- public static void initialization() throws Exception {
- final Collection<File> testFiles = TestRestconfUtils.loadFiles("/instanceidentifier/yang");
- testFiles.addAll(TestRestconfUtils.loadFiles("/invoke-rpc"));
- schemaContext = YangParserTestUtils.parseYangFiles(testFiles);
- }
-
- @Test
- public void rpcModuleInputTest() throws Exception {
- final String uri = "invoke-rpc-module:rpc-test";
- final String pathToInputFile = "/invoke-rpc/xml/rpc-output.xml";
- final NormalizedNodeContext nnContext = TestRestconfUtils
- .loadNormalizedContextFromXmlFile(pathToInputFile, uri, controllerContext);
- final OutputStream output = new ByteArrayOutputStream();
- this.xmlBodyWriter.writeTo(nnContext, null, null, null, this.mediaType, null, output);
- assertTrue(output.toString().contains("lf-test"));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.controller.sal.rest.impl.test.providers;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThrows;
-
-import java.io.InputStream;
-import javax.ws.rs.core.MediaType;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.netconf.sal.rest.impl.XmlToPatchBodyReader;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.patch.PatchContext;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-
-public class TestXmlPatchBodyReader extends AbstractBodyReaderTest {
-
- private final XmlToPatchBodyReader xmlToPatchBodyReader;
- private static EffectiveModelContext schemaContext;
-
- public TestXmlPatchBodyReader() {
- super(schemaContext, null);
- xmlToPatchBodyReader = new XmlToPatchBodyReader(controllerContext);
- }
-
- @Override
- protected MediaType getMediaType() {
- return new MediaType(MediaType.APPLICATION_XML, null);
- }
-
- @BeforeClass
- public static void initialization() throws NoSuchFieldException, SecurityException {
- schemaContext = schemaContextLoader("/instanceidentifier/yang", schemaContext);
- }
-
- @Test
- public void moduleDataTest() throws Exception {
- final String uri = "instance-identifier-patch-module:patch-cont/my-list1/leaf1";
- mockBodyReader(uri, xmlToPatchBodyReader, false);
- final InputStream inputStream = TestXmlBodyReader.class.getResourceAsStream(
- "/instanceidentifier/xml/xmlPATCHdata.xml");
- final PatchContext returnValue = xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream);
- checkPatchContext(returnValue);
- }
-
- /**
- * Test trying to use Patch create operation which requires value without value. Error code 400 should be returned.
- */
- @Test
- public void moduleDataValueMissingNegativeTest() throws Exception {
- final String uri = "instance-identifier-patch-module:patch-cont/my-list1/leaf1";
- mockBodyReader(uri, xmlToPatchBodyReader, false);
- final InputStream inputStream = TestXmlBodyReader.class.getResourceAsStream(
- "/instanceidentifier/xml/xmlPATCHdataValueMissing.xml");
- final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
- () -> xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream));
- assertEquals(1, ex.getErrors().size());
- assertEquals(ErrorTag.MALFORMED_MESSAGE, ex.getErrors().get(0).getErrorTag());
- }
-
- /**
- * Test trying to use value with Patch delete operation which does not support value. Error code 400 should be
- * returned.
- */
- @Test
- public void moduleDataNotValueNotSupportedNegativeTest() throws Exception {
- final String uri = "instance-identifier-patch-module:patch-cont/my-list1/leaf1";
- mockBodyReader(uri, xmlToPatchBodyReader, false);
- final InputStream inputStream = TestXmlBodyReader.class.getResourceAsStream(
- "/instanceidentifier/xml/xmlPATCHdataValueNotSupported.xml");
-
- final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
- () -> xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream));
- assertEquals(1, ex.getErrors().size());
- assertEquals(ErrorTag.MALFORMED_MESSAGE, ex.getErrors().get(0).getErrorTag());
- }
-
- /**
- * Test of Yang Patch with absolute target path.
- */
- @Test
- public void moduleDataAbsoluteTargetPathTest() throws Exception {
- final String uri = "";
- mockBodyReader(uri, xmlToPatchBodyReader, false);
- final InputStream inputStream = TestXmlBodyReader.class
- .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataAbsoluteTargetPath.xml");
- final PatchContext returnValue = xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream);
- checkPatchContext(returnValue);
- }
-
- /**
- * Test using Patch when target is completely specified in request URI and thus target leaf contains only '/' sign.
- */
- @Test
- public void modulePatchCompleteTargetInURITest() throws Exception {
- final String uri = "instance-identifier-patch-module:patch-cont";
- mockBodyReader(uri, xmlToPatchBodyReader, false);
- final InputStream inputStream = TestXmlBodyReader.class
- .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataCompleteTargetInURI.xml");
- final PatchContext returnValue = xmlToPatchBodyReader
- .readFrom(null, null, null, mediaType, null, inputStream);
- checkPatchContext(returnValue);
- }
-
- /**
- * Test of Yang Patch merge operation on list. Test consists of two edit operations - replace and merge.
- */
- @Test
- public void moduleDataMergeOperationOnListTest() throws Exception {
- final String uri = "instance-identifier-patch-module:patch-cont/my-list1/leaf1";
- mockBodyReader(uri, xmlToPatchBodyReader, false);
- final InputStream inputStream = TestXmlBodyReader.class
- .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataMergeOperationOnList.xml");
- final PatchContext returnValue = xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream);
- checkPatchContext(returnValue);
- }
-
- /**
- * Test of Yang Patch merge operation on container. Test consists of two edit operations - create and merge.
- */
- @Test
- public void moduleDataMergeOperationOnContainerTest() throws Exception {
- final String uri = "instance-identifier-patch-module:patch-cont";
- mockBodyReader(uri, xmlToPatchBodyReader, false);
- final InputStream inputStream = TestXmlBodyReader.class
- .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataMergeOperationOnContainer.xml");
- final PatchContext returnValue = xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream);
- checkPatchContext(returnValue);
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.rest.impl.test.providers;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThrows;
-import static org.mockito.Mockito.mock;
-
-import java.io.InputStream;
-import javax.ws.rs.core.MediaType;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.mdsal.dom.api.DOMMountPoint;
-import org.opendaylight.netconf.sal.rest.impl.XmlToPatchBodyReader;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.patch.PatchContext;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-
-public class TestXmlPatchBodyReaderMountPoint extends AbstractBodyReaderTest {
-
- private final XmlToPatchBodyReader xmlToPatchBodyReader;
- private static EffectiveModelContext schemaContext;
- private static final String MOUNT_POINT = "instance-identifier-module:cont/yang-ext:mount";
-
- public TestXmlPatchBodyReaderMountPoint() {
- super(schemaContext, mock(DOMMountPoint.class));
- xmlToPatchBodyReader = new XmlToPatchBodyReader(controllerContext);
- }
-
- @BeforeClass
- public static void initialization() throws NoSuchFieldException, SecurityException {
- schemaContext = schemaContextLoader("/instanceidentifier/yang", schemaContext);
- }
-
- @Override
- protected MediaType getMediaType() {
- return new MediaType(MediaType.APPLICATION_XML, null);
- }
-
- @Test
- public void moduleDataTest() throws Exception {
- final String uri = MOUNT_POINT + "/instance-identifier-patch-module:patch-cont/my-list1/leaf1";
- mockBodyReader(uri, xmlToPatchBodyReader, false);
- final InputStream inputStream = TestXmlBodyReader.class.getResourceAsStream(
- "/instanceidentifier/xml/xmlPATCHdata.xml");
- checkPatchContextMountPoint(xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream));
- }
-
- /**
- * Test trying to use Patch create operation which requires value without value. Error code 400 should be returned.
- */
- @Test
- public void moduleDataValueMissingNegativeTest() throws Exception {
- final String uri = MOUNT_POINT + "/instance-identifier-patch-module:patch-cont/my-list1/leaf1";
- mockBodyReader(uri, xmlToPatchBodyReader, false);
- final InputStream inputStream = TestXmlBodyReader.class.getResourceAsStream(
- "/instanceidentifier/xml/xmlPATCHdataValueMissing.xml");
- final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
- () -> xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream));
- assertEquals(ErrorTag.MALFORMED_MESSAGE, ex.getErrors().get(0).getErrorTag());
- }
-
- /**
- * Test trying to use value with Patch delete operation which does not support value. Error code 400 should be
- * returned.
- */
- @Test
- public void moduleDataNotValueNotSupportedNegativeTest() throws Exception {
- final String uri = MOUNT_POINT + "/instance-identifier-patch-module:patch-cont/my-list1/leaf1";
- mockBodyReader(uri, xmlToPatchBodyReader, false);
- final InputStream inputStream = TestXmlBodyReader.class
- .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataValueNotSupported.xml");
- final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
- () -> xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream));
- assertEquals(ErrorTag.MALFORMED_MESSAGE, ex.getErrors().get(0).getErrorTag());
- }
-
- /**
- * Test of Yang Patch with absolute target path.
- */
- @Test
- public void moduleDataAbsoluteTargetPathTest() throws Exception {
- final String uri = MOUNT_POINT;
- mockBodyReader(uri, xmlToPatchBodyReader, false);
- final InputStream inputStream = TestXmlBodyReader.class.getResourceAsStream(
- "/instanceidentifier/xml/xmlPATCHdataAbsoluteTargetPath.xml");
- final PatchContext returnValue = xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream);
- checkPatchContextMountPoint(returnValue);
- }
-
- /**
- * Test using Patch when target is completely specified in request URI and thus target leaf contains only '/' sign.
- */
- @Test
- public void modulePatchCompleteTargetInURITest() throws Exception {
- final String uri = MOUNT_POINT + "/instance-identifier-patch-module:patch-cont";
- mockBodyReader(uri, xmlToPatchBodyReader, false);
- final InputStream inputStream = TestXmlBodyReader.class.getResourceAsStream(
- "/instanceidentifier/xml/xmlPATCHdataCompleteTargetInURI.xml");
- final PatchContext returnValue = xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream);
- checkPatchContextMountPoint(returnValue);
- }
-
- /**
- * Test of Yang Patch merge operation on list. Test consists of two edit operations - replace and merge.
- */
- @Test
- public void moduleDataMergeOperationOnListTest() throws Exception {
- final String uri = MOUNT_POINT + "/instance-identifier-patch-module:patch-cont/my-list1/leaf1";
- mockBodyReader(uri, xmlToPatchBodyReader, false);
- final InputStream inputStream = TestXmlBodyReader.class.getResourceAsStream(
- "/instanceidentifier/xml/xmlPATCHdataMergeOperationOnList.xml");
- checkPatchContextMountPoint(xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream));
- }
-
- /**
- * Test of Yang Patch merge operation on container. Test consists of two edit operations - create and merge.
- */
- @Test
- public void moduleDataMergeOperationOnContainerTest() throws Exception {
- final String uri = MOUNT_POINT + "/instance-identifier-patch-module:patch-cont";
- mockBodyReader(uri, xmlToPatchBodyReader, false);
- final InputStream inputStream = TestXmlBodyReader.class.getResourceAsStream(
- "/instanceidentifier/xml/xmlPATCHdataMergeOperationOnContainer.xml");
- checkPatchContextMountPoint(xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream));
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.cnsn.to.json.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonToken;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
-import org.junit.BeforeClass;
-import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
-
-public class CnSnToJsonBasicDataTypesTest extends YangAndXmlAndDataSchemaLoader {
-
- abstract static class LeafVerifier {
-
- Object expectedValue;
- JsonToken expectedToken;
-
- LeafVerifier(final Object expectedValue, final JsonToken expectedToken) {
- this.expectedValue = expectedValue;
- this.expectedToken = expectedToken;
- }
-
- abstract Object getActualValue(JsonReader reader) throws IOException;
-
- void verify(final JsonReader reader, final String keyName) throws IOException {
- assertEquals("Json value for key " + keyName, this.expectedValue, getActualValue(reader));
- }
-
- JsonToken expectedTokenType() {
- return this.expectedToken;
- }
- }
-
- static class BooleanVerifier extends LeafVerifier {
-
- BooleanVerifier(final boolean expected) {
- super(expected, JsonToken.BOOLEAN);
- }
-
- @Override
- Object getActualValue(final JsonReader reader) throws IOException {
- return reader.nextBoolean();
- }
- }
-
- static class NumberVerifier extends LeafVerifier {
-
- NumberVerifier(final Number expected) {
- super(expected, JsonToken.NUMBER);
- }
-
- @Override
- Object getActualValue(final JsonReader reader) throws IOException {
- if (this.expectedValue instanceof Double) {
- return reader.nextDouble();
- } else if (this.expectedValue instanceof Long) {
- return reader.nextLong();
- } else if (this.expectedValue instanceof Integer) {
- return reader.nextInt();
- }
-
- return null;
- }
- }
-
- static class StringVerifier extends LeafVerifier {
-
- StringVerifier(final String expected) {
- super(expected, JsonToken.STRING);
- }
-
- @Override
- Object getActualValue(final JsonReader reader) throws IOException {
- return reader.nextString();
- }
- }
-
- static class EmptyVerifier extends LeafVerifier {
-
- EmptyVerifier() {
- super(null, null);
- }
-
- @Override
- Object getActualValue(final JsonReader reader) throws IOException {
- reader.beginArray();
- reader.nextNull();
- reader.endArray();
- return null;
- }
-
- }
-
- static class ComplexAnyXmlVerifier extends LeafVerifier {
-
- ComplexAnyXmlVerifier() {
- super(null, JsonToken.BEGIN_OBJECT);
- }
-
- @Override
- void verify(final JsonReader reader, final String keyName) throws IOException {
-
- reader.beginObject();
- final String innerKey = reader.nextName();
- assertEquals("Json reader child key for " + keyName, "data", innerKey);
- assertEquals("Json token type for key " + innerKey, JsonToken.BEGIN_OBJECT, reader.peek());
-
- reader.beginObject();
- verifyLeaf(reader, innerKey, "leaf1", "leaf1-value");
- verifyLeaf(reader, innerKey, "leaf2", "leaf2-value");
-
- String nextName = reader.nextName();
- assertEquals("Json reader child key for " + innerKey, "leaf-list", nextName);
- reader.beginArray();
- assertEquals("Json value for key " + nextName, "leaf-list-value1", reader.nextString());
- assertEquals("Json value for key " + nextName, "leaf-list-value2", reader.nextString());
- reader.endArray();
-
- nextName = reader.nextName();
- assertEquals("Json reader child key for " + innerKey, "list", nextName);
- reader.beginArray();
- verifyNestedLists(reader, 1);
- verifyNestedLists(reader, 3);
- reader.endArray();
-
- reader.endObject();
- reader.endObject();
- }
-
- void verifyNestedLists(final JsonReader reader, int leafNum) throws IOException {
- reader.beginObject();
-
- final String nextName = reader.nextName();
- assertEquals("Json reader next name", "nested-list", nextName);
-
- reader.beginArray();
-
- reader.beginObject();
- verifyLeaf(reader, "nested-list", "nested-leaf", "nested-value" + leafNum++);
- reader.endObject();
-
- reader.beginObject();
- verifyLeaf(reader, "nested-list", "nested-leaf", "nested-value" + leafNum);
- reader.endObject();
-
- reader.endArray();
- reader.endObject();
- }
-
- void verifyLeaf(final JsonReader reader, final String parent, final String name,
- final String value) throws IOException {
- final String nextName = reader.nextName();
- assertEquals("Json reader child key for " + parent, name, nextName);
- assertEquals("Json token type for key " + parent, JsonToken.STRING, reader.peek());
- assertEquals("Json value for key " + nextName, value, reader.nextString());
- }
-
- @Override
- Object getActualValue(final JsonReader reader) throws IOException {
- return null;
- }
- }
-
- @BeforeClass
- public static void initialize() throws FileNotFoundException {
- dataLoad("/cnsn-to-json/simple-data-types");
- }
-
- private static void verifyJsonOutput(final String jsonOutput) {
- final StringReader strReader = new StringReader(jsonOutput);
- final JsonReader jReader = new JsonReader(strReader);
-
- String exception = null;
- try {
- jsonReadCont(jReader);
- } catch (final IOException e) {
- exception = e.getMessage();
- }
-
- assertNull("Error during reading Json output: " + exception, exception);
- }
-
- private static void jsonReadCont(final JsonReader jsonReader) throws IOException {
- jsonReader.beginObject();
- assertNotNull("cont1 is missing.", jsonReader.hasNext());
-
- // Cont dataFromJson = new Cont(jReader.nextName());
- jsonReader.nextName();
- jsonReadContElements(jsonReader);
-
- assertFalse("cont shouldn't have other element.", jsonReader.hasNext());
- jsonReader.endObject();
- // return dataFromJson;
- }
-
- private static void jsonReadContElements(final JsonReader jsonReader) throws IOException {
- jsonReader.beginObject();
-
- final Map<String, LeafVerifier> expectedMap = new HashMap<>();
- expectedMap.put("lfnint8Min", new NumberVerifier(-128));
- expectedMap.put("lfnint8Max", new NumberVerifier(127));
- expectedMap.put("lfnint16Min", new NumberVerifier(-32768));
- expectedMap.put("lfnint16Max", new NumberVerifier(32767));
- expectedMap.put("lfnint32Min", new NumberVerifier(-2147483648));
- expectedMap.put("lfnint32Max", new NumberVerifier(2147483647L));
- expectedMap.put("lfnint64Min", new NumberVerifier(-9223372036854775808L));
- expectedMap.put("lfnint64Max", new NumberVerifier(9223372036854775807L));
- expectedMap.put("lfnuint8Max", new NumberVerifier(255));
- expectedMap.put("lfnuint16Max", new NumberVerifier(65535));
- expectedMap.put("lfnuint32Max", new NumberVerifier(4294967295L));
- expectedMap.put("lfstr", new StringVerifier("lfstr"));
- expectedMap.put("lfstr1", new StringVerifier(""));
- expectedMap.put("lfbool1", new BooleanVerifier(true));
- expectedMap.put("lfbool2", new BooleanVerifier(false));
- expectedMap.put("lfbool3", new BooleanVerifier(false));
- expectedMap.put("lfdecimal1", new NumberVerifier(43.32));
- expectedMap.put("lfdecimal2", new NumberVerifier(-0.43));
- expectedMap.put("lfdecimal3", new NumberVerifier(43d));
- expectedMap.put("lfdecimal4", new NumberVerifier(43E3));
- expectedMap.put("lfdecimal6", new NumberVerifier(33.12345));
- expectedMap.put("lfenum", new StringVerifier("enum3"));
- expectedMap.put("lfbits", new StringVerifier("bit3 bit2"));
- expectedMap.put("lfbinary", new StringVerifier("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
- expectedMap.put("lfunion1", new StringVerifier("324"));
- expectedMap.put("lfunion2", new StringVerifier("33.3"));
- expectedMap.put("lfunion3", new StringVerifier("55"));
- expectedMap.put("lfunion4", new StringVerifier("true"));
- expectedMap.put("lfunion5", new StringVerifier("true"));
- expectedMap.put("lfunion6", new StringVerifier("10"));
- expectedMap.put("lfunion7", new StringVerifier(""));
- expectedMap.put("lfunion8", new StringVerifier(""));
- expectedMap.put("lfunion9", new StringVerifier(""));
- expectedMap.put("lfunion10", new StringVerifier("bt1"));
- expectedMap.put("lfunion11", new StringVerifier("33"));
- expectedMap.put("lfunion12", new StringVerifier("false"));
- expectedMap.put("lfunion13", new StringVerifier("b1"));
- expectedMap.put("lfunion14", new StringVerifier("zero"));
- expectedMap.put("lfempty", new EmptyVerifier());
- expectedMap.put("identityref1", new StringVerifier("simple-data-types:iden"));
- expectedMap.put("complex-any", new ComplexAnyXmlVerifier());
- expectedMap.put("simple-any", new StringVerifier("simple"));
- expectedMap.put("empty-any", new StringVerifier(""));
-
- while (jsonReader.hasNext()) {
- final String keyName = jsonReader.nextName();
- final JsonToken peek = jsonReader.peek();
-
- final LeafVerifier verifier = expectedMap.remove(keyName);
- assertNotNull("Found unexpected leaf: " + keyName, verifier);
-
- final JsonToken expToken = verifier.expectedTokenType();
- if (expToken != null) {
- assertEquals("Json token type for key " + keyName, expToken, peek);
- }
-
- verifier.verify(jsonReader, keyName);
- }
-
- if (!expectedMap.isEmpty()) {
- fail("Missing leaf nodes in Json output: " + expectedMap.keySet());
- }
-
- jsonReader.endObject();
- }
-
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.cnsn.to.json.test;
-
-import java.io.FileNotFoundException;
-import org.junit.BeforeClass;
-import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
-
-public class CnSnToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader {
-
- @BeforeClass
- public static void initialization() throws FileNotFoundException, ReactorException {
- dataLoad("/cnsn-to-json/identityref", 2, "identityref-module", "cont");
- }
-
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.cnsn.to.json.test;
-
-import java.io.FileNotFoundException;
-import org.junit.BeforeClass;
-import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
-
-public class CnSnToJsonWithDataFromSeveralModulesTest extends YangAndXmlAndDataSchemaLoader {
-
- @BeforeClass
- public static void initialize() throws FileNotFoundException, ReactorException {
- dataLoad("/xml-to-cnsn/data-of-several-modules/yang", 2, "module1", "cont_m1");
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.input.to.cnsn.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import com.google.common.util.concurrent.FluentFuture;
-import java.io.FileNotFoundException;
-import java.util.List;
-import javax.ws.rs.core.Response.Status;
-import javax.ws.rs.core.UriInfo;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.restconf.impl.BrokerFacade;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.netconf.sal.restconf.impl.PutResult;
-import org.opendaylight.netconf.sal.restconf.impl.RestconfImpl;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.errors.RestconfError;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.common.ErrorType;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.NormalizedNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.SchemaAwareBuilders;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.valid.DataValidationException;
-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.util.SchemaInferenceStack;
-
-public class RestPutListDataTest {
- private static EffectiveModelContext schemaContextTestModule;
-
- private static BrokerFacade brokerFacade;
- private static RestconfImpl restconfImpl;
-
- private static final String TEST_MODULE_NS_STRING = "test:module";
- private static final String TEST_MODULE_REVISION = "2014-01-09";
-
- @BeforeClass
- public static void staticSetup() throws FileNotFoundException {
- schemaContextTestModule = TestUtils.loadSchemaContext("/full-versions/test-module");
- }
-
- @Before
- public void initialize() throws FileNotFoundException {
- final ControllerContext controllerContext = TestRestconfUtils.newControllerContext(schemaContextTestModule);
- brokerFacade = mock(BrokerFacade.class);
- restconfImpl = RestconfImpl.newInstance(brokerFacade, controllerContext);
- final PutResult result = mock(PutResult.class);
- when(brokerFacade.commitConfigurationDataPut(any(EffectiveModelContext.class),
- any(YangInstanceIdentifier.class), any(NormalizedNode.class), Mockito.anyString(), Mockito.anyString()))
- .thenReturn(result);
- when(result.getFutureOfPutData()).thenReturn(mock(FluentFuture.class));
- when(result.getStatus()).thenReturn(Status.OK);
- }
-
- /**
- * Tests whether no exception is raised if number and values of keys in URI
- * and payload are equal.
- */
- @Test
- @Ignore
- public void testValidKeys() {
- putListDataTest("key1value", "15", "key1value", (short) 15);
- }
-
- /**
- * Tests whether an exception is raised if key values in URI and payload are
- * different.
- *
- * <p>
- * The exception should be raised from validation method
- * {@code RestconfImpl#validateListEqualityOfListInDataAndUri}
- */
- @Test
- @Ignore // RestconfDocumentedExceptionMapper needs update
- public void testUriAndPayloadKeysDifferent() {
- try {
- putListDataTest("key1value", "15", "key1value", (short) 16);
- fail("RestconfDocumentedException expected");
- } catch (final RestconfDocumentedException e) {
- verifyException(e, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
-
- try {
- putListDataTest("key1value", "15", "key1value1", (short) 16);
- fail("RestconfDocumentedException expected");
- } catch (final RestconfDocumentedException e) {
- verifyException(e, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
- }
- }
-
- /**
- * Tests whether an exception is raised if URI contains less key values then
- * payload.
- *
- * <p>
- * The exception is raised during {@code InstanceIdentifier} instance is
- * built from URI
- */
- @Test
- @Ignore
- public void testMissingKeysInUri() {
- try {
- putListDataTest("key1value", null, "key1value", (short) 15);
- fail("RestconfDocumentedException expected");
- } catch (final RestconfDocumentedException e) {
- verifyException(e, ErrorType.PROTOCOL, ErrorTag.DATA_MISSING);
- }
- }
-
- /**
- * Tests whether an exception is raised if URI contains more key values then
- * payload.
- *
- * <p>
- * The exception should be raised from validation method
- * {@code RestconfImpl#validateListEqualityOfListInDataAndUri}
- */
- @Test
- public void testMissingKeysInPayload() {
- try {
- putListDataTest("key1value", "15", "key1value", null);
- fail("RestconfDocumentedException expected");
- } catch (final DataValidationException e) {
- // FIXME: thing about different approach for testing the Exception states
- // RestconfDocumentedException is not rise in new API because you get
- // DataValidationException from putListDataTest before you call the real rest service
-// verifyException(e, ErrorType.PROTOCOL, ErrorTag.DATA_MISSING);
- }
- }
-
- private static void verifyException(final RestconfDocumentedException restDocumentedException,
- final ErrorType errorType, final ErrorTag errorTag) {
- final List<RestconfError> errors = restDocumentedException.getErrors();
- assertEquals("getErrors() size", 1, errors.size());
- assertEquals("RestconfError getErrorType()", errorType, errors.get(0).getErrorType());
- assertEquals("RestconfError getErrorTag()", errorTag, errors.get(0).getErrorTag());
- }
-
- public void putListDataTest(final String uriKey1, final String uriKey2, final String payloadKey1,
- final Short payloadKey2) {
- final QName lstWithCompositeKey =
- QName.create(TEST_MODULE_NS_STRING, TEST_MODULE_REVISION, "lst-with-composite-key");
- final QName key1 = QName.create(TEST_MODULE_NS_STRING, TEST_MODULE_REVISION, "key1");
- final QName key2 = QName.create(TEST_MODULE_NS_STRING, TEST_MODULE_REVISION, "key2");
-
- final DataSchemaNode testNodeSchemaNode = schemaContextTestModule.getDataChildByName(lstWithCompositeKey);
- assertTrue(testNodeSchemaNode != null);
- assertTrue(testNodeSchemaNode instanceof ListSchemaNode);
- final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> testNodeContainer =
- SchemaAwareBuilders.mapEntryBuilder((ListSchemaNode) testNodeSchemaNode);
-
- var testChildren = ControllerContext.findInstanceDataChildrenByName(
- (ListSchemaNode) testNodeSchemaNode, key1.getLocalName());
- assertTrue(testChildren != null);
- final DataSchemaNode testLeafKey1SchemaNode = testChildren.get(0).child;
- assertTrue(testLeafKey1SchemaNode != null);
- assertTrue(testLeafKey1SchemaNode instanceof LeafSchemaNode);
- final NormalizedNodeBuilder<NodeIdentifier, Object, LeafNode<Object>> leafKey1 =
- SchemaAwareBuilders.leafBuilder((LeafSchemaNode) testLeafKey1SchemaNode);
- leafKey1.withValue(payloadKey1);
- testNodeContainer.withChild(leafKey1.build());
-
- if (payloadKey2 != null) {
- testChildren = ControllerContext.findInstanceDataChildrenByName(
- (ListSchemaNode) testNodeSchemaNode, key2.getLocalName());
- assertTrue(testChildren != null);
- final DataSchemaNode testLeafKey2SchemaNode = testChildren.get(0).child;
- assertNotNull(testLeafKey2SchemaNode);
- assertTrue(testLeafKey2SchemaNode instanceof LeafSchemaNode);
- final NormalizedNodeBuilder<NodeIdentifier, Object, LeafNode<Object>> leafKey2 =
- SchemaAwareBuilders.leafBuilder((LeafSchemaNode) testLeafKey2SchemaNode);
- leafKey2.withValue(payloadKey2);
- testNodeContainer.withChild(leafKey2.build());
- }
-
- final NormalizedNodeContext testCompositeContext = new NormalizedNodeContext(
- InstanceIdentifierContext.ofStack(
- SchemaInferenceStack.ofDataTreePath(schemaContextTestModule, lstWithCompositeKey)),
- testNodeContainer.build());
-
- final UriInfo uriInfo = Mockito.mock(UriInfo.class);
- restconfImpl.updateConfigurationData(toUri(uriKey1, uriKey2), testCompositeContext, uriInfo);
- }
-
- public void putListDataWithWrapperTest(final String uriKey1, final String uriKey2, final String payloadKey1,
- final Short payloadKey2) {
- putListDataTest(uriKey1, uriKey2, payloadKey1, payloadKey2);
- }
-
- private static String toUri(final String uriKey1, final String uriKey2) {
- final StringBuilder uriBuilder = new StringBuilder("/test-module:lst-with-composite-key/");
- uriBuilder.append(uriKey1);
- if (uriKey2 != null) {
- uriBuilder.append("/");
- uriBuilder.append(uriKey2);
- }
- return uriBuilder.toString();
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.json.to.nn.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.InputStream;
-import javax.ws.rs.core.MediaType;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.sal.rest.impl.test.providers.AbstractBodyReaderTest;
-import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-
-public class JsonIdentityrefToNnTest extends AbstractBodyReaderTest {
-
- private final JsonNormalizedNodeBodyReader jsonBodyReader;
- private static EffectiveModelContext schemaContext;
-
- public JsonIdentityrefToNnTest() {
- super(schemaContext, null);
- this.jsonBodyReader = new JsonNormalizedNodeBodyReader(controllerContext);
- }
-
- @BeforeClass
- public static void initialize() {
- schemaContext = schemaContextLoader("/json-to-nn/identityref", schemaContext);
- }
-
- @Test
- public void jsonIdentityrefToNn() throws Exception {
-
- final String uri = "identityref-module:cont";
- mockBodyReader(uri, this.jsonBodyReader, false);
- final InputStream inputStream = this.getClass().getResourceAsStream(
- "/json-to-nn/identityref/json/data.json");
-
- final NormalizedNodeContext normalizedNodeContext = this.jsonBodyReader.readFrom(
- null, null, null, this.mediaType, null, inputStream);
-
- assertEquals("cont", normalizedNodeContext.getData().getIdentifier().getNodeType().getLocalName());
-
- final String dataTree = NormalizedNodes.toStringTree(normalizedNodeContext.getData());
-
- assertTrue(dataTree.contains("cont1"));
- assertTrue(dataTree
- .contains("lf11 (identity:module?revision=2013-12-02)iden"));
- assertTrue(dataTree
- .contains("lf12 (identityref:module?revision=2013-12-02)iden_local"));
- assertTrue(dataTree
- .contains("lf13 (identityref:module?revision=2013-12-02)iden_local"));
- assertTrue(dataTree
- .contains("lf14 (identity:module?revision=2013-12-02)iden"));
- }
-
- @Override
- protected MediaType getMediaType() {
- return null;
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.json.to.nn.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.InputStream;
-import javax.ws.rs.core.MediaType;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.sal.rest.impl.test.providers.AbstractBodyReaderTest;
-import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-
-public class JsonLeafrefToNnTest extends AbstractBodyReaderTest {
-
- private final JsonNormalizedNodeBodyReader jsonBodyReader;
- private static EffectiveModelContext schemaContext;
-
- public JsonLeafrefToNnTest() {
- super(schemaContext, null);
- this.jsonBodyReader = new JsonNormalizedNodeBodyReader(controllerContext);
- }
-
- @BeforeClass
- public static void initialize() {
- schemaContext = schemaContextLoader("/json-to-nn/leafref", schemaContext);
- }
-
- @Test
- public void jsonIdentityrefToNormalizeNode() throws Exception {
-
- final String uri = "leafref-module:cont";
- mockBodyReader(uri, this.jsonBodyReader, false);
- final InputStream inputStream = this.getClass().getResourceAsStream(
- "/json-to-nn/leafref/json/data.json");
-
- final NormalizedNodeContext normalizedNodeContext = this.jsonBodyReader.readFrom(
- null, null, null, this.mediaType, null, inputStream);
-
- assertEquals("cont", normalizedNodeContext.getData().getIdentifier().getNodeType().getLocalName());
- final String dataTree = NormalizedNodes.toStringTree(normalizedNodeContext.getData());
- assertTrue(dataTree.contains("lf2 121"));
- }
-
- @Override
- protected MediaType getMediaType() {
- return null;
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.json.to.nn.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.util.Collection;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.controller.sal.rest.impl.test.providers.AbstractBodyReaderTest;
-import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class JsonToNnTest extends AbstractBodyReaderTest {
-
- private static final Logger LOG = LoggerFactory.getLogger(AbstractBodyReaderTest.class);
-
- private final JsonNormalizedNodeBodyReader jsonBodyReader;
- private static EffectiveModelContext schemaContext;
-
- public JsonToNnTest() {
- super(schemaContext, null);
- this.jsonBodyReader = new JsonNormalizedNodeBodyReader(controllerContext);
- }
-
- @BeforeClass
- public static void initialize() throws FileNotFoundException {
- final Collection<File> testFiles = TestRestconfUtils.loadFiles("/json-to-nn/simple-list-yang/1");
- testFiles.addAll(TestRestconfUtils.loadFiles("/json-to-nn/simple-list-yang/3"));
- testFiles.addAll(TestRestconfUtils.loadFiles("/json-to-nn/simple-list-yang/4"));
- testFiles.addAll(TestRestconfUtils.loadFiles("/json-to-nn/simple-container-yang"));
- testFiles.addAll(TestRestconfUtils.loadFiles("/common/augment/yang"));
- schemaContext = YangParserTestUtils.parseYangFiles(testFiles);
- }
-
- @Test
- public void simpleListTest() throws Exception {
- simpleTest("/json-to-nn/simple-list.json",
- "lst", "simple-list-yang1");
- }
-
- @Test
- public void simpleContainerTest() throws Exception {
- simpleTest("/json-to-nn/simple-container.json",
- "cont", "simple-container-yang");
- }
-
- @Test
- public void multipleItemsInLeafListTest() throws Exception {
- final NormalizedNodeContext normalizedNodeContext = prepareNNC(
- "/json-to-nn/multiple-leaflist-items.json",
- "simple-list-yang1:lst");
- assertNotNull(normalizedNodeContext);
-
- final String dataTree = NormalizedNodes.toStringTree(normalizedNodeContext
- .getData());
- assertTrue(dataTree.contains("45"));
- assertTrue(dataTree.contains("55"));
- assertTrue(dataTree.contains("66"));
- }
-
- @Test
- public void multipleItemsInListTest() throws Exception {
- final NormalizedNodeContext normalizedNodeContext = prepareNNC(
- "/json-to-nn/multiple-items-in-list.json",
- "multiple-items-yang:lst");
- assertNotNull(normalizedNodeContext);
-
- assertEquals("lst", normalizedNodeContext.getData().getIdentifier().getNodeType().getLocalName());
-
- verityMultipleItemsInList(normalizedNodeContext);
- }
-
- @Test
- public void nullArrayToSimpleNodeWithNullValueTest() throws Exception {
- final NormalizedNodeContext normalizedNodeContext = prepareNNC(
- "/json-to-nn/array-with-null.json", "array-with-null-yang:cont");
- assertNotNull(normalizedNodeContext);
-
- assertEquals("cont", normalizedNodeContext.getData().getIdentifier().getNodeType().getLocalName());
-
- final String dataTree = NormalizedNodes.toStringTree(normalizedNodeContext.getData());
- assertTrue(dataTree.contains("lf"));
- assertTrue(dataTree.contains("empty"));
- }
-
- @Test
- public void incorrectTopLevelElementsTest() throws Exception {
- mockBodyReader("simple-list-yang1:lst", this.jsonBodyReader, false);
-
- InputStream inputStream = this.getClass().getResourceAsStream(
- "/json-to-nn/wrong-top-level1.json");
-
- int countExceptions = 0;
- RestconfDocumentedException exception = null;
-
- try {
- this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
- inputStream);
- } catch (final RestconfDocumentedException e) {
- exception = e;
- countExceptions++;
- }
- assertNotNull(exception);
- assertEquals(
- "Error parsing input: Schema node with name wrong was not found under "
- + "(urn:ietf:params:xml:ns:netconf:base:1.0)data.",
- exception.getErrors().get(0).getErrorMessage());
-
- inputStream = this.getClass().getResourceAsStream(
- "/json-to-nn/wrong-top-level2.json");
- exception = null;
- try {
- this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
- inputStream);
- } catch (final RestconfDocumentedException e) {
- exception = e;
- countExceptions++;
- }
- assertNotNull(exception);
- assertEquals(
- "Error parsing input: Schema node with name lst1 was not found under "
- + "(urn:ietf:params:xml:ns:netconf:base:1.0)data.",
- exception.getErrors().get(0).getErrorMessage());
-
- inputStream = this.getClass().getResourceAsStream(
- "/json-to-nn/wrong-top-level3.json");
- exception = null;
- try {
- this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
- inputStream);
- } catch (final RestconfDocumentedException e) {
- exception = e;
- countExceptions++;
- }
- assertNotNull(exception);
- assertEquals(
- "Error parsing input: Schema node with name lf was not found under "
- + "(urn:ietf:params:xml:ns:netconf:base:1.0)data.",
- exception.getErrors().get(0).getErrorMessage());
- assertEquals(3, countExceptions);
- }
-
- @Test
- public void emptyDataReadTest() throws Exception {
- final NormalizedNodeContext normalizedNodeContext = prepareNNC(
- "/json-to-nn/empty-data.json", "array-with-null-yang:cont");
- assertNotNull(normalizedNodeContext);
-
- assertEquals("cont", normalizedNodeContext.getData().getIdentifier().getNodeType().getLocalName());
-
- final String dataTree = NormalizedNodes.toStringTree(normalizedNodeContext.getData());
-
- assertTrue(dataTree.contains("lflst1"));
-
- assertTrue(dataTree.contains("lflst2 45"));
-
- RestconfDocumentedException exception = null;
- mockBodyReader("array-with-null-yang:cont", this.jsonBodyReader, false);
- final InputStream inputStream = this.getClass().getResourceAsStream("/json-to-nn/empty-data.json1");
-
- try {
- this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,inputStream);
- } catch (final RestconfDocumentedException e) {
- exception = e;
- }
- assertNotNull(exception);
- assertEquals("Error parsing input: null", exception.getErrors().get(0).getErrorMessage());
- }
-
- @Test
- public void testJsonBlankInput() throws Exception {
- final NormalizedNodeContext normalizedNodeContext = prepareNNC("", "array-with-null-yang:cont");
- assertNull(normalizedNodeContext);
- }
-
- @Test
- public void notSupplyNamespaceIfAlreadySupplied()throws Exception {
- final String uri = "simple-list-yang1" + ":" + "lst";
-
- final NormalizedNodeContext normalizedNodeContext = prepareNNC("/json-to-nn/simple-list.json", uri);
- assertNotNull(normalizedNodeContext);
-
- verifyNormaluizedNodeContext(normalizedNodeContext, "lst");
-
- mockBodyReader("simple-list-yang2:lst", this.jsonBodyReader, false);
- final InputStream inputStream = this.getClass().getResourceAsStream("/json-to-nn/simple-list.json");
-
- try {
- this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null, inputStream);
- fail("NormalizedNodeContext should not be create because of different namespace");
- } catch (final RestconfDocumentedException e) {
- LOG.warn("Read from InputStream failed. Message: {}. Status: {}", e.getMessage(), e.getStatus());
- }
-
- verifyNormaluizedNodeContext(normalizedNodeContext, "lst");
- }
-
- @Test
- public void dataAugmentedTest() throws Exception {
- NormalizedNodeContext normalizedNodeContext = prepareNNC("/common/augment/json/dataa.json", "main:cont");
-
- assertNotNull(normalizedNodeContext);
- assertEquals("cont", normalizedNodeContext.getData().getIdentifier().getNodeType().getLocalName());
-
- String dataTree = NormalizedNodes.toStringTree(normalizedNodeContext
- .getData());
- assertTrue(dataTree.contains("cont1"));
- assertTrue(dataTree.contains("lf11 lf11 value from a"));
-
- normalizedNodeContext = prepareNNC("/common/augment/json/datab.json", "main:cont");
-
- assertNotNull(normalizedNodeContext);
- assertEquals("cont", normalizedNodeContext.getData().getIdentifier().getNodeType().getLocalName());
- dataTree = NormalizedNodes.toStringTree(normalizedNodeContext.getData());
- assertTrue(dataTree.contains("cont1"));
- assertTrue(dataTree.contains("lf11 lf11 value from b"));
- }
-
- private void simpleTest(final String jsonPath, final String topLevelElementName,
- final String moduleName) throws Exception {
- final String uri = moduleName + ":" + topLevelElementName;
-
- final NormalizedNodeContext normalizedNodeContext = prepareNNC(jsonPath, uri);
- assertNotNull(normalizedNodeContext);
-
- verifyNormaluizedNodeContext(normalizedNodeContext, topLevelElementName);
- }
-
- private NormalizedNodeContext prepareNNC(final String jsonPath, final String uri) throws Exception {
- try {
- mockBodyReader(uri, this.jsonBodyReader, false);
- } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
- LOG.warn("Operation failed due to: {}", e.getMessage());
- }
- final InputStream inputStream = this.getClass().getResourceAsStream(jsonPath);
-
- NormalizedNodeContext normalizedNodeContext = null;
-
- try {
- normalizedNodeContext = this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null, inputStream);
- } catch (WebApplicationException e) {
- // TODO Auto-generated catch block
- }
-
- return normalizedNodeContext;
- }
-
- private static void verifyNormaluizedNodeContext(final NormalizedNodeContext normalizedNodeContext,
- final String topLevelElementName) {
- assertEquals(topLevelElementName, normalizedNodeContext.getData().getIdentifier().getNodeType().getLocalName());
-
- final String dataTree = NormalizedNodes.toStringTree(normalizedNodeContext.getData());
- assertTrue(dataTree.contains("cont1"));
- assertTrue(dataTree.contains("lst1"));
- assertTrue(dataTree.contains("lflst1"));
- assertTrue(dataTree.contains("lflst1_1"));
- assertTrue(dataTree.contains("lflst1_2"));
- assertTrue(dataTree.contains("lf1"));
- }
-
- private static void verityMultipleItemsInList(final NormalizedNodeContext normalizedNodeContext) {
- final String dataTree = NormalizedNodes.toStringTree(normalizedNodeContext.getData());
- assertTrue(dataTree.contains("lf11"));
- assertTrue(dataTree.contains("lf11_1"));
- assertTrue(dataTree.contains("lflst11"));
- assertTrue(dataTree.contains("45"));
- assertTrue(dataTree.contains("cont11"));
- assertTrue(dataTree.contains("lst11"));
- }
-
- @Test
- public void unsupportedDataFormatTest() throws Exception {
- mockBodyReader("simple-list-yang1:lst", this.jsonBodyReader, false);
-
- final InputStream inputStream = this.getClass().getResourceAsStream("/json-to-nn/unsupported-json-format.json");
-
- RestconfDocumentedException exception = null;
-
- try {
- this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null, inputStream);
- } catch (final RestconfDocumentedException e) {
- exception = e;
- }
- LOG.info(exception.getErrors().get(0).getErrorMessage());
-
- assertTrue(exception.getErrors().get(0).getErrorMessage().contains("is not a simple type"));
- }
-
- @Test
- public void invalidUriCharacterInValue() throws Exception {
- mockBodyReader("array-with-null-yang:cont", this.jsonBodyReader, false);
-
- final InputStream inputStream = this.getClass().getResourceAsStream(
- "/json-to-nn/invalid-uri-character-in-value.json");
-
- final NormalizedNodeContext normalizedNodeContext = this.jsonBodyReader.readFrom(
- null, null, null, this.mediaType, null, inputStream);
- assertNotNull(normalizedNodeContext);
-
- assertEquals("cont", normalizedNodeContext.getData().getIdentifier().getNodeType().getLocalName());
-
- final String dataTree = NormalizedNodes.toStringTree(normalizedNodeContext.getData());
- assertTrue(dataTree.contains("lf1 module<Name:value lf1"));
- assertTrue(dataTree.contains("lf2 module>Name:value lf2"));
- }
-
- @Override
- protected MediaType getMediaType() {
- return null;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.controller.sal.restconf.impl.nn.to.json.test;
-
-import static org.junit.Assert.assertTrue;
-
-import java.io.ByteArrayOutputStream;
-import java.io.OutputStream;
-import javax.ws.rs.core.MediaType;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.controller.sal.rest.impl.test.providers.AbstractBodyReaderTest;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeJsonBodyWriter;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-
-public class NnJsonChoiceCaseTest extends AbstractBodyReaderTest {
-
- private static EffectiveModelContext schemaContext;
- private final NormalizedNodeJsonBodyWriter jsonBodyWriter;
-
- public NnJsonChoiceCaseTest() {
- super(schemaContext, null);
- jsonBodyWriter = new NormalizedNodeJsonBodyWriter();
- }
-
- @BeforeClass
- public static void initialization() {
- schemaContext = schemaContextLoader("/nn-to-json/choice", schemaContext);
- }
-
- /**
- * Test when some data are in one case node and other in another. This isn't
- * correct. Next Json validator should return error because nodes has to be
- * from one case below concrete choice.
- */
- @Test(expected = NullPointerException.class)
- public void nodeSchemasOnVariousChoiceCasePathTest() throws Exception {
- getJson("/nn-to-json/choice/xml/data_various_path_err.xml");
- }
-
- /**
- * Test when some data are in one case node and other in another.
- * Additionally data are loadef from various choices. This isn't correct.
- * Next Json validator should return error because nodes has to be from one
- * case below concrete choice.
- */
- @Test(expected = NullPointerException.class)
- public void nodeSchemasOnVariousChoiceCasePathAndMultipleChoicesTest()
- throws Exception {
- getJson("/nn-to-json/choice/xml/data_more_choices_same_level_various_paths_err.xml");
- }
-
- /**
- * Test when second level data are red first, then first and at the end
- * third level. Level represents pass through couple choice-case
- */
-
- @Test
- public void nodeSchemasWithRandomOrderAccordingLevel() throws Exception {
- final String json = getJson("/nn-to-json/choice/xml/data_random_level.xml");
-
- assertTrue(json.contains("cont"));
- assertTrue(json.contains("\"lf1\":\"lf1 val\""));
- assertTrue(json.contains("\"lf1aaa\":\"lf1aaa val\""));
- assertTrue(json.contains("\"lf1aa\":\"lf1aa val\""));
- assertTrue(json.contains("\"lf1a\":121"));
- }
-
- /**
- * Test when element from no first case is used.
- */
- @Test
- public void nodeSchemasNotInFirstCase() throws Exception {
- final String json = getJson("/nn-to-json/choice/xml/data_no_first_case.xml");
-
- assertTrue(json.contains("cont"));
- assertTrue(json.contains("\"lf1\":\"lf1 val\""));
- assertTrue(json.contains("\"lf1ab\":\"lf1ab val\""));
- assertTrue(json.contains("\"lf1a\":121"));
- }
-
- /**
- * Test when element in case is list.
- */
- @Test
- public void nodeSchemaAsList() throws Exception {
- final String json = getJson("/nn-to-json/choice/xml/data_list.xml");
-
- assertTrue(json.contains("cont"));
- assertTrue(json.contains("\"lst1b\":["));
- assertTrue(json.contains("{\"lf11b\":\"lf11b_1 val\"}"));
- assertTrue(json.contains("{\"lf11b\":\"lf11b_2 val\"}"));
- }
-
- /**
- * Test when element in case is container.
- */
- @Test
- public void nodeSchemaAsContainer() throws Exception {
- final String json = getJson("/nn-to-json/choice/xml/data_container.xml");
-
- assertTrue(json.contains("cont"));
- assertTrue(json.contains("\"cont1c\":{"));
- assertTrue(json.contains("\"lf11c\":\"lf11c val\""));
- }
-
- /**
- * Test when element in case is leaflist.
- */
- @Test
- public void nodeSchemaAsLeafList() throws Exception {
- final String json = getJson("/nn-to-json/choice/xml/data_leaflist.xml");
-
- assertTrue(json.contains("cont"));
- assertTrue(json.contains("\"lflst1d\":["));
- assertTrue(json.contains("\"lflst1d_1 val\""));
- assertTrue(json.contains("\"lflst1d_2 val\""));
- }
-
- @Test
- public void nodeSchemasInMultipleChoicesTest() throws Exception {
- final String json = getJson("/nn-to-json/choice/xml/data_more_choices_same_level.xml");
-
- assertTrue(json.contains("cont"));
- assertTrue(json.contains("\"lf2b\":\"lf2b value\""));
- assertTrue(json.contains("\"cont1c\":{"));
- assertTrue(json.contains("\"lf11c\":\"lf11c val\""));
- }
-
- /**
- * Test whether is possible to find data schema for node which is specified
- * as dirrect subnode of choice (case without CASE key word).
- */
- @Test
- public void nodeSchemasInCaseNotDefinedWithCaseKeyword() throws Exception {
- final String json = getJson("/nn-to-json/choice/xml/data_case_defined_without_case.xml");
-
- assertTrue(json.contains("cont"));
- assertTrue(json.contains("\"lf2b\":\"lf2b val\""));
- assertTrue(json.contains("\"e1\":45"));
- }
-
- /**
- * Test of multiple use of choices.
- */
- @Test
- public void nodeSchemasInThreeChoicesAtSameLevel() throws Exception {
- final String json = getJson("/nn-to-json/choice/xml/data_three_choices_same_level.xml");
-
- assertTrue(json.contains("cont"));
- assertTrue(json.contains("lf2b\":\"lf2b value"));
- assertTrue(json.contains("lst4a\":[{"));
- assertTrue(json.contains("{\"lf4ab\":33}"));
- assertTrue(json.contains("{\"lf4ab\":37}"));
- assertTrue(json.contains("\"lf1aaa\":\"lf1aaa value\""));
- }
-
- private String getJson(final String xmlPath) throws Exception {
- final String uri = "choice-case-test:cont";
- final NormalizedNodeContext testNN = TestRestconfUtils
- .loadNormalizedContextFromXmlFile(xmlPath, uri, controllerContext);
-
- final OutputStream output = new ByteArrayOutputStream();
- jsonBodyWriter.writeTo(testNN, null, null, null, mediaType, null,
- output);
-
- return output.toString();
- }
-
- @Override
- protected MediaType getMediaType() {
- return null;
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.nn.to.json.test;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.ByteArrayOutputStream;
-import java.io.OutputStream;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.ws.rs.core.MediaType;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.controller.sal.rest.impl.test.providers.AbstractBodyReaderTest;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeJsonBodyWriter;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-
-public class NnToJsonLeafrefType extends AbstractBodyReaderTest {
-
- private static EffectiveModelContext schemaContext;
- private final NormalizedNodeJsonBodyWriter jsonBodyWriter;
-
- public NnToJsonLeafrefType() {
- super(schemaContext, null);
- jsonBodyWriter = new NormalizedNodeJsonBodyWriter();
- }
-
- @BeforeClass
- public static void initialization() {
- schemaContext = schemaContextLoader("/nn-to-json/leafref", schemaContext);
- }
-
- @Test
- public void leafrefAbsolutePathToExistingLeafTest() throws Exception {
- final String json = toJson("/nn-to-json/leafref/xml/data_absolut_ref_to_existing_leaf.xml");
- validateJson(".*\"lf3\":\\p{Blank}*\"true\".*", json);
- }
-
- @Test
- public void leafrefRelativePathToExistingLeafTest() throws Exception {
- final String json = toJson("/nn-to-json/leafref/xml/data_relativ_ref_to_existing_leaf.xml");
- validateJson(".*\"lf2\":\\p{Blank}*\"121\".*", json);
- }
-
- @Test(expected = NullPointerException.class)
- public void leafrefToNonExistingLeafTest() throws Exception {
- toJson("/nn-to-json/leafref/xml/data_ref_to_non_existing_leaf.xml");
- }
-
- @Test
- public void leafrefToNotLeafTest() throws Exception {
- final String json = toJson("/nn-to-json/leafref/xml/data_ref_to_not_leaf.xml");
- validateJson(
- ".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lf6\":\\p{Blank}*\"44\".*",
- json);
- }
-
- @Test
- public void leafrefFromLeafListToLeafTest() throws Exception {
- final String json = toJson("/nn-to-json/leafref/xml/data_relativ_ref_from_leaflist_to_existing_leaf.xml");
- validateJson(".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lflst1\":\\p{Blank}*.*\"34[5|6|7]\",*\"34[5|6|7]\","
- + "*\"34[5|6|7]\".*", json);
- }
-
- @Test
- public void leafrefFromLeafrefToLeafrefTest() throws Exception {
- final String json = toJson("/nn-to-json/leafref/xml/data_from_leafref_to_leafref.xml");
- validateJson(
- ".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lf7\":\\p{Blank}*\"200\".*",
- json);
- }
-
- private static void validateJson(final String regex, final String value) {
- assertNotNull(value);
- final Pattern ptrn = Pattern.compile(regex, Pattern.DOTALL);
- final Matcher mtch = ptrn.matcher(value);
- assertTrue(mtch.matches());
- }
-
- private String toJson(final String xmlDataPath) throws Exception {
- final String uri = "main-module:cont";
- final String pathToInputFile = xmlDataPath;
-
- final NormalizedNodeContext testNN = TestRestconfUtils
- .loadNormalizedContextFromXmlFile(pathToInputFile, uri, controllerContext);
-
- final OutputStream output = new ByteArrayOutputStream();
- jsonBodyWriter.writeTo(testNN, null, null, null, mediaType, null,
- output);
- final String jsonOutput = output.toString();
-
- return jsonOutput;
- }
-
- @Override
- protected MediaType getMediaType() {
- return new MediaType(MediaType.APPLICATION_XML, null);
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.nn.to.json.test;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.controller.sal.rest.impl.test.providers.AbstractBodyReaderTest;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeJsonBodyWriter;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-
-@Deprecated
-public class NnToJsonWithAugmentTest extends AbstractBodyReaderTest {
-
- private static EffectiveModelContext schemaContext;
- private final NormalizedNodeJsonBodyWriter xmlBodyWriter;
-
- public NnToJsonWithAugmentTest() {
- super(schemaContext, null);
- xmlBodyWriter = new NormalizedNodeJsonBodyWriter();
- }
-
- @BeforeClass
- public static void initialize() {
- schemaContext = schemaContextLoader("/nn-to-json/augmentation", schemaContext);
- }
-
- @Test
- public void augmentedElementsToJson() throws WebApplicationException,
- IOException {
- final String uri = "yang:cont";
- final String pathToInputFile = "/nn-to-json/augmentation/xml/data.xml";
-
- final NormalizedNodeContext testNN = TestRestconfUtils
- .loadNormalizedContextFromXmlFile(pathToInputFile, uri, controllerContext);
-
- final OutputStream output = new ByteArrayOutputStream();
- xmlBodyWriter
- .writeTo(testNN, null, null, null, mediaType, null, output);
- final String jsonOutput = output.toString();
-
- assertNotNull(jsonOutput);
- assertTrue(jsonOutput.contains("\"cont1\"" + ":" + '{'));
- assertTrue(jsonOutput.contains("\"lf11\"" + ":" + "\"lf11\""));
- assertTrue(jsonOutput.contains("\"lst1\"" + ":" + '['));
- assertTrue(jsonOutput.contains("\"lf11\"" + ":" + "\"lf1_1\""));
- assertTrue(jsonOutput.contains("\"lf11\"" + ":" + "\"lf1_2\""));
- assertTrue(jsonOutput.contains("\"lflst1\"" + ":" + "["));
- assertTrue(jsonOutput.contains("\"lf2\"" + ":" + "\"lf2\""));
- }
-
- @Override
- protected MediaType getMediaType() {
- return new MediaType(MediaType.APPLICATION_XML, null);
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.nn.to.xml.test;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.ByteArrayOutputStream;
-import java.io.OutputStream;
-import java.net.URISyntaxException;
-import javax.ws.rs.core.MediaType;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.sal.rest.impl.test.providers.AbstractBodyReaderTest;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeXmlBodyWriter;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.SystemLeafSetNode;
-import org.opendaylight.yangtools.yang.data.api.schema.SystemMapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.CollectionNodeBuilder;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.ListNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.SchemaAwareBuilders;
-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.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
-
-public class NnInstanceIdentifierToXmlTest extends AbstractBodyReaderTest {
- private static EffectiveModelContext schemaContext;
-
- private final NormalizedNodeXmlBodyWriter xmlBodyWriter = new NormalizedNodeXmlBodyWriter();
-
- public NnInstanceIdentifierToXmlTest() {
- super(schemaContext, null);
- }
-
- @BeforeClass
- public static void initialization() throws URISyntaxException {
- schemaContext = schemaContextLoader("/instanceidentifier/yang", schemaContext);
- }
-
- @Test
- public void nnAsYangInstanceIdentifierAugmentLeafList() throws Exception {
- final NormalizedNodeContext normalizedNodeContext = prepareNNCLeafList();
-
- final OutputStream output = new ByteArrayOutputStream();
-
- xmlBodyWriter.writeTo(normalizedNodeContext, null, null, null, mediaType, null, output);
-
- assertNotNull(output);
-
- final String outputJson = output.toString();
-
- assertTrue(outputJson.contains("<cont xmlns="));
- assertTrue(outputJson.contains(
- '"' + "instance:identifier:module" + '"'));
- assertTrue(outputJson.contains(">"));
-
- assertTrue(outputJson.contains("<cont1>"));
-
- assertTrue(outputJson.contains("<lf11 xmlns="));
- assertTrue(outputJson.contains(
- '"' + "augment:module:leaf:list" + '"'));
- assertTrue(outputJson.contains(">"));
- assertTrue(outputJson.contains("/instanceidentifier/"));
- assertTrue(outputJson.contains("</lf11>"));
-
- assertTrue(outputJson.contains("<lflst11 xmlns="));
- assertTrue(outputJson.contains(
- '"' + "augment:module:leaf:list" + '"'));
- assertTrue(outputJson.contains(">"));
- assertTrue(outputJson.contains("lflst11 value"));
- assertTrue(outputJson.contains("</lflst11>"));
-
- assertTrue(outputJson.contains("</cont1>"));
- assertTrue(outputJson.contains("</cont>"));
- }
-
- private static NormalizedNodeContext prepareNNCLeafList() throws URISyntaxException {
- final QName cont = QName.create("instance:identifier:module", "2014-01-17",
- "cont");
- final QName cont1 = QName.create("instance:identifier:module", "2014-01-17",
- "cont1");
- final QName lflst11 = QName.create("augment:module:leaf:list", "2014-01-17",
- "lflst11");
- final QName lf11 = QName.create("augment:module:leaf:list", "2014-01-17",
- "lf11");
-
- final DataSchemaNode schemaCont = schemaContext.getDataChildByName(cont);
-
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> dataCont = SchemaAwareBuilders
- .containerBuilder((ContainerSchemaNode) schemaCont);
-
- final DataSchemaNode schemaCont1 = ((ContainerSchemaNode) schemaCont).getDataChildByName(cont1);
-
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> dataCont1 = SchemaAwareBuilders
- .containerBuilder((ContainerSchemaNode) schemaCont1);
-
- final var instanceLfLst11 = ControllerContext.findInstanceDataChildrenByName(
- (DataNodeContainer) schemaCont1, lflst11.getLocalName());
-
- final DataSchemaNode lfLst11Schema = instanceLfLst11.get(0).child;
- final ListNodeBuilder<Object, SystemLeafSetNode<Object>> lfLst11Data = SchemaAwareBuilders
- .leafSetBuilder((LeafListSchemaNode) lfLst11Schema);
-
- lfLst11Data.withChild(SchemaAwareBuilders.leafSetEntryBuilder((LeafListSchemaNode) lfLst11Schema)
- .withValue("lflst11 value").build());
- dataCont1.withChild(lfLst11Data.build());
-
- final var instanceLf11 = ControllerContext.findInstanceDataChildrenByName(
- (DataNodeContainer) schemaCont1, lf11.getLocalName());
- final DataSchemaNode lf11Schema = instanceLf11.get(0).child;
-
- dataCont1.withChild(SchemaAwareBuilders.leafBuilder((LeafSchemaNode) lf11Schema)
- .withValue("/instanceidentifier/").build());
- dataCont.withChild(dataCont1.build());
-
- return new NormalizedNodeContext(
- InstanceIdentifierContext.ofStack(SchemaInferenceStack.ofDataTreePath(schemaContext, cont)),
- dataCont.build());
- }
-
- @Test
- public void nnAsYangInstanceIdentifierAugment() throws Exception {
-
- final NormalizedNodeContext normalizedNodeContext = preparNNC();
- final OutputStream output = new ByteArrayOutputStream();
-
- xmlBodyWriter.writeTo(normalizedNodeContext, null, null, null,
- mediaType, null, output);
-
- assertNotNull(output);
-
- final String outputJson = output.toString();
-
- assertTrue(outputJson.contains("<cont xmlns="));
- assertTrue(outputJson.contains(
- '"' + "instance:identifier:module" + '"'));
- assertTrue(outputJson.contains(">"));
-
- assertTrue(outputJson.contains("<cont1>"));
-
- assertTrue(outputJson.contains("<lst11 xmlns="));
- assertTrue(outputJson.contains('"' + "augment:module" + '"'));
- assertTrue(outputJson.contains(">"));
-
- assertTrue(outputJson.contains(
- "<keyvalue111>keyvalue111</keyvalue111>"));
- assertTrue(outputJson.contains(
- "<keyvalue112>keyvalue112</keyvalue112>"));
-
- assertTrue(outputJson.contains("<lf111 xmlns="));
- assertTrue(outputJson.contains(
- '"' + "augment:augment:module" + '"'));
- assertTrue(outputJson.contains(">/cont/cont1/lf12</lf111>"));
-
- assertTrue(outputJson.contains("<lf112 xmlns="));
- assertTrue(outputJson.contains(
- '"' + "augment:augment:module" + '"'));
- assertTrue(outputJson.contains(">lf12 value</lf112>"));
-
- assertTrue(outputJson.contains("</lst11></cont1></cont>"));
- }
-
- private static NormalizedNodeContext preparNNC() {
- final QName cont = QName.create("instance:identifier:module", "2014-01-17",
- "cont");
- final QName cont1 = QName.create("instance:identifier:module", "2014-01-17",
- "cont1");
- final QName lst11 = QName.create("augment:module", "2014-01-17", "lst11");
- final QName lf11 = QName.create("augment:augment:module", "2014-01-17",
- "lf111");
- final QName lf12 = QName.create("augment:augment:module", "2014-01-17",
- "lf112");
- final QName keyvalue111 = QName.create("augment:module", "2014-01-17",
- "keyvalue111");
- final QName keyvalue112 = QName.create("augment:module", "2014-01-17",
- "keyvalue112");
-
- final DataSchemaNode schemaCont = schemaContext.getDataChildByName(cont);
-
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> dataCont = SchemaAwareBuilders
- .containerBuilder((ContainerSchemaNode) schemaCont);
-
- final DataSchemaNode schemaCont1 = ((ContainerSchemaNode) schemaCont)
- .getDataChildByName(cont1);
-
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> dataCont1 = SchemaAwareBuilders
- .containerBuilder((ContainerSchemaNode) schemaCont1);
-
- final var instanceLst11 = ControllerContext.findInstanceDataChildrenByName(
- (DataNodeContainer) schemaCont1, lst11.getLocalName());
- final DataSchemaNode lst11Schema = instanceLst11.get(0).child;
-
- final CollectionNodeBuilder<MapEntryNode, SystemMapNode> dataLst11 = SchemaAwareBuilders
- .mapBuilder((ListSchemaNode) lst11Schema);
-
- final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> dataLst11Vaule = SchemaAwareBuilders
- .mapEntryBuilder((ListSchemaNode) lst11Schema);
-
- dataLst11Vaule.withChild(buildLeaf(lst11Schema, keyvalue111, dataLst11, "keyvalue111"));
-
- dataLst11Vaule.withChild(buildLeaf(lst11Schema, keyvalue112, dataLst11, "keyvalue112"));
-
- dataLst11Vaule.withChild(buildLeaf(lst11Schema, lf11, dataLst11, "/cont/cont1/lf12"));
-
- dataLst11Vaule.withChild(buildLeaf(lst11Schema, lf12, dataLst11, "lf12 value"));
-
- dataLst11.withChild(dataLst11Vaule.build());
-
- dataCont1.withChild(dataLst11.build());
- dataCont.withChild(dataCont1.build());
-
- return new NormalizedNodeContext(
- InstanceIdentifierContext.ofStack(SchemaInferenceStack.ofDataTreePath(schemaContext, cont)),
- dataCont.build());
- }
-
- private static DataContainerChild buildLeaf(final DataSchemaNode lst11Schema, final QName qname,
- final CollectionNodeBuilder<MapEntryNode, SystemMapNode> dataLst11, final Object value) {
-
- final var instanceLf = ControllerContext.findInstanceDataChildrenByName(
- (DataNodeContainer) lst11Schema, qname.getLocalName());
- final DataSchemaNode schemaLf = instanceLf.get(0).child;
-
- return SchemaAwareBuilders.leafBuilder((LeafSchemaNode) schemaLf).withValue(value).build();
- }
-
- @Override
- protected MediaType getMediaType() {
- return null;
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.nn.to.xml.test;
-
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.assertTrue;
-
-import com.google.common.base.Throwables;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import javax.ws.rs.core.MediaType;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.opendaylight.controller.sal.rest.impl.test.providers.AbstractBodyReaderTest;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeXmlBodyWriter;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.Uint32;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
-import org.opendaylight.yangtools.yang.data.impl.schema.SchemaAwareBuilders;
-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.type.BitsTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
-import org.opendaylight.yangtools.yang.model.ri.type.BaseTypes;
-import org.opendaylight.yangtools.yang.model.ri.type.BitsTypeBuilder;
-import org.opendaylight.yangtools.yang.model.ri.type.EnumerationTypeBuilder;
-import org.opendaylight.yangtools.yang.model.ri.type.UnionTypeBuilder;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
-
-public class NnToXmlTest extends AbstractBodyReaderTest {
- private static EffectiveModelContext schemaContext;
-
- private final NormalizedNodeXmlBodyWriter xmlBodyWriter;
-
- public NnToXmlTest() {
- super(schemaContext, null);
- xmlBodyWriter = new NormalizedNodeXmlBodyWriter();
- }
-
- @BeforeClass
- public static void initialization() {
- schemaContext = schemaContextLoader("/nn-to-xml/yang", schemaContext);
- }
-
- @Test
- public void nnAsYangIdentityrefToXMLTest() throws Exception {
- final NormalizedNodeContext normalizedNodeContext = prepareIdrefData(null, true);
- nnToXml(normalizedNodeContext, "<lf11 xmlns:x=\"referenced:module\">x:iden</lf11>");
- }
-
- @Test
- public void nnAsYangIdentityrefWithQNamePrefixToXMLTest() throws Exception {
- final NormalizedNodeContext normalizedNodeContext = prepareIdrefData("prefix", true);
- nnToXml(normalizedNodeContext, "<lf11 xmlns", "=\"referenced:module\">", ":iden</lf11>");
- }
-
- @Test
- public void nnAsYangIdentityrefWithPrefixToXMLTest() throws Exception {
- final NormalizedNodeContext normalizedNodeContext = prepareIdrefData("prefix", false);
- nnToXml(normalizedNodeContext, "<lf11>no qname value</lf11>");
- }
-
- @Test
- public void nnAsYangLeafrefWithPrefixToXMLTest() throws Exception {
- nnToXml(prepareLeafrefData(), "<lfBoolean>true</lfBoolean>", "<lfLfref>true</lfLfref>");
- }
-
- /**
- * Negative test when leaf of type leafref references to not-existing leaf.
- * {@code VerifyException} is expected.
- */
- @Test
- public void nnAsYangLeafrefWithPrefixToXMLNegativeTest() throws Exception {
- final NormalizedNodeContext normalizedNodeContext = prepareLeafrefNegativeData();
-
- final IOException ex = assertThrows(IOException.class, () -> nnToXml(normalizedNodeContext,
- "<not-existing>value</not-existing>", "<lfLfrefNegative>value</lfLfrefnegative>"));
- final Throwable rootCause = Throwables.getRootCause(ex);
- assertThat(rootCause, instanceOf(IllegalArgumentException.class));
- assertEquals("Data tree child (basic:module?revision=2013-12-02)not-existing not present in schema parent "
- + "(basic:module?revision=2013-12-02)cont", rootCause.getMessage());
- }
-
- @Test
- public void nnAsYangStringToXmlTest() throws Exception {
- final NormalizedNodeContext normalizedNodeContext = prepareNNC(
- TypeDefinitionAwareCodec.from(BaseTypes.stringType()).deserialize("lfStr value"), "lfStr");
- nnToXml(normalizedNodeContext, "<lfStr>lfStr value</lfStr>");
- }
-
- @Test
- public void nnAsYangInt8ToXmlTest() throws Exception {
- final String elName = "lfInt8";
-
- final NormalizedNodeContext normalizedNodeContext = prepareNNC(
- TypeDefinitionAwareCodec.from(BaseTypes.int8Type()).deserialize("14"), elName);
- nnToXml(normalizedNodeContext, "<" + elName + ">14</" + elName + ">");
- }
-
- @Test
- public void nnAsYangInt16ToXmlTest() throws Exception {
- final String elName = "lfInt16";
-
- final NormalizedNodeContext normalizedNodeContext = prepareNNC(
- TypeDefinitionAwareCodec.from(BaseTypes.int16Type()).deserialize("3000"), elName);
- nnToXml(normalizedNodeContext, "<" + elName + ">3000</" + elName + ">");
- }
-
- @Test
- public void nnAsYangInt32ToXmlTest() throws Exception {
- final String elName = "lfInt32";
-
- final NormalizedNodeContext normalizedNodeContext = prepareNNC(
- TypeDefinitionAwareCodec.from(BaseTypes.int32Type()).deserialize("201234"), elName);
- nnToXml(normalizedNodeContext, "<" + elName + ">201234</" + elName + ">");
- }
-
- @Test
- public void nnAsYangInt64ToXmlTest() throws Exception {
- final String elName = "lfInt64";
-
- final NormalizedNodeContext normalizedNodeContext = prepareNNC(
- TypeDefinitionAwareCodec.from(BaseTypes.int64Type()).deserialize("5123456789"), elName);
- nnToXml(normalizedNodeContext, "<" + elName + ">5123456789</" + elName + ">");
- }
-
- @Test
- public void nnAsYangUint8ToXmlTest() throws Exception {
- final String elName = "lfUint8";
-
- final NormalizedNodeContext normalizedNodeContext = prepareNNC(
- TypeDefinitionAwareCodec.from(BaseTypes.uint8Type()).deserialize("200"), elName);
- nnToXml(normalizedNodeContext, "<" + elName + ">200</" + elName + ">");
- }
-
- @Test
- public void snAsYangUint16ToXmlTest() throws Exception {
- final String elName = "lfUint16";
-
- final NormalizedNodeContext normalizedNodeContext = prepareNNC(
- TypeDefinitionAwareCodec.from(BaseTypes.uint16Type()).deserialize("4000"), elName);
- nnToXml(normalizedNodeContext, "<" + elName + ">4000</" + elName + ">");
- }
-
- @Test
- public void nnAsYangUint32ToXmlTest() throws Exception {
- final String elName = "lfUint32";
-
- final NormalizedNodeContext normalizedNodeContext = prepareNNC(
- TypeDefinitionAwareCodec.from(BaseTypes.uint32Type()).deserialize("4123456789"), elName);
- nnToXml(normalizedNodeContext, "<" + elName + ">4123456789</" + elName + ">");
- }
-
- @Test
- public void snAsYangUint64ToXmlTest() throws Exception {
- final String elName = "lfUint64";
- final NormalizedNodeContext normalizedNodeContext = prepareNNC(
- TypeDefinitionAwareCodec.from(BaseTypes.uint64Type()).deserialize("5123456789"), elName);
- nnToXml(normalizedNodeContext, "<" + elName + ">5123456789</" + elName + ">");
- }
-
- @Test
- public void nnAsYangBinaryToXmlTest() throws Exception {
- final String elName = "lfBinary";
- final NormalizedNodeContext normalizedNodeContext = prepareNNC(
- TypeDefinitionAwareCodec.from(BaseTypes.binaryType())
- .deserialize("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567"),
- elName);
- nnToXml(normalizedNodeContext,
- "<" + elName + ">ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567</" + elName + ">");
- }
-
- @Test
- public void nnAsYangBitsToXmlTest() throws Exception {
- final BitsTypeDefinition.Bit mockBit1 = Mockito.mock(BitsTypeDefinition.Bit.class);
- Mockito.when(mockBit1.getName()).thenReturn("one");
- Mockito.when(mockBit1.getPosition()).thenReturn(Uint32.ONE);
- final BitsTypeDefinition.Bit mockBit2 = Mockito.mock(BitsTypeDefinition.Bit.class);
- Mockito.when(mockBit2.getName()).thenReturn("two");
- Mockito.when(mockBit2.getPosition()).thenReturn(Uint32.TWO);
- final BitsTypeBuilder bitsTypeBuilder = BaseTypes.bitsTypeBuilder(QName.create("foo", "foo"));
- bitsTypeBuilder.addBit(mockBit1);
- bitsTypeBuilder.addBit(mockBit2);
-
- final String elName = "lfBits";
- final NormalizedNodeContext normalizedNodeContext = prepareNNC(
- TypeDefinitionAwareCodec.from(bitsTypeBuilder.build()).deserialize("one two"), elName);
- nnToXml(normalizedNodeContext, "<" + elName + ">one two</" + elName + ">");
- }
-
- @Test
- public void nnAsYangEnumerationToXmlTest() throws Exception {
- final EnumTypeDefinition.EnumPair mockEnum = Mockito.mock(EnumTypeDefinition.EnumPair.class);
- Mockito.when(mockEnum.getName()).thenReturn("enum2");
-
- final EnumerationTypeBuilder enumerationTypeBuilder = BaseTypes
- .enumerationTypeBuilder(QName.create("foo", "foo"));
- enumerationTypeBuilder.addEnum(mockEnum);
-
- final String elName = "lfEnumeration";
- final NormalizedNodeContext normalizedNodeContext = prepareNNC(
- TypeDefinitionAwareCodec.from(enumerationTypeBuilder.build()).deserialize("enum2"), elName);
- nnToXml(normalizedNodeContext, "<" + elName + ">enum2</" + elName + ">");
- }
-
- @Test
- public void nnAsYangEmptyToXmlTest() throws Exception {
- final String elName = "lfEmpty";
- final NormalizedNodeContext normalizedNodeContext = prepareNNC(
- TypeDefinitionAwareCodec.from(BaseTypes.emptyType()).deserialize(""), elName);
- nnToXml(normalizedNodeContext, "<" + elName + "/>");
- }
-
- @Test
- public void nnAsYangBooleanToXmlTest() throws Exception {
- final String elName = "lfBoolean";
- NormalizedNodeContext normalizedNodeContext = prepareNNC(
- TypeDefinitionAwareCodec.from(BaseTypes.booleanType()).deserialize("false"), elName);
- nnToXml(normalizedNodeContext, "<" + elName + ">false</" + elName + ">");
-
- normalizedNodeContext = prepareNNC(TypeDefinitionAwareCodec.from(BaseTypes.booleanType()).deserialize("true"),
- elName);
- nnToXml(normalizedNodeContext, "<" + elName + ">true</" + elName + ">");
- }
-
- @Test
- public void nnAsYangUnionToXmlTest() throws Exception {
- final BitsTypeDefinition.Bit mockBit1 = Mockito.mock(BitsTypeDefinition.Bit.class);
- Mockito.when(mockBit1.getName()).thenReturn("first");
- Mockito.when(mockBit1.getPosition()).thenReturn(Uint32.ONE);
- final BitsTypeDefinition.Bit mockBit2 = Mockito.mock(BitsTypeDefinition.Bit.class);
- Mockito.when(mockBit2.getName()).thenReturn("second");
- Mockito.when(mockBit2.getPosition()).thenReturn(Uint32.TWO);
-
- final BitsTypeBuilder bitsTypeBuilder = BaseTypes.bitsTypeBuilder(QName.create("foo", "foo"));
- bitsTypeBuilder.addBit(mockBit1);
- bitsTypeBuilder.addBit(mockBit2);
-
- final UnionTypeBuilder unionTypeBuilder = BaseTypes.unionTypeBuilder(QName.create("foo", "foo"));
- unionTypeBuilder.addType(BaseTypes.int8Type());
- unionTypeBuilder.addType(bitsTypeBuilder.build());
- unionTypeBuilder.addType(BaseTypes.booleanType());
- unionTypeBuilder.addType(BaseTypes.stringType());
-
- final String elName = "lfUnion";
-
- // test int8
- final String int8 = "15";
- NormalizedNodeContext normalizedNodeContext = prepareNNC(
- TypeDefinitionAwareCodec.from(unionTypeBuilder.build()).deserialize(int8), elName);
- nnToXml(normalizedNodeContext, "<" + elName + ">15</" + elName + ">");
-
- // test bits
- final String bits = "first second";
- normalizedNodeContext = prepareNNC(TypeDefinitionAwareCodec.from(unionTypeBuilder.build()).deserialize(bits),
- elName);
- nnToXml(normalizedNodeContext, "<" + elName + ">[first, second]</" + elName + ">");
-
- // test boolean
- final String bool = "true";
- normalizedNodeContext = prepareNNC(TypeDefinitionAwareCodec.from(unionTypeBuilder.build()).deserialize(bool),
- elName);
- nnToXml(normalizedNodeContext, "<" + elName + ">true</" + elName + ">");
-
- // test string
- final String s = "Hi!";
- normalizedNodeContext = prepareNNC(TypeDefinitionAwareCodec.from(unionTypeBuilder.build()).deserialize(s),
- elName);
- nnToXml(normalizedNodeContext, "<" + elName + ">Hi!</" + elName + ">");
- }
-
- private static NormalizedNodeContext prepareNNC(final Object object, final String name) {
- final QName cont = QName.create("basic:module", "2013-12-02", "cont");
- final QName lf = QName.create("basic:module", "2013-12-02", name);
-
- final DataSchemaNode contSchema = schemaContext.getDataChildByName(cont);
-
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> contData = SchemaAwareBuilders
- .containerBuilder((ContainerSchemaNode) contSchema);
-
- final var instanceLf = ControllerContext
- .findInstanceDataChildrenByName((DataNodeContainer) contSchema, lf.getLocalName());
- final DataSchemaNode schemaLf = instanceLf.get(0).child;
-
- contData.withChild(SchemaAwareBuilders.leafBuilder((LeafSchemaNode) schemaLf).withValue(object).build());
-
- return new NormalizedNodeContext(
- InstanceIdentifierContext.ofStack(SchemaInferenceStack.ofDataTreePath(schemaContext, cont)),
- contData.build());
- }
-
- private void nnToXml(final NormalizedNodeContext normalizedNodeContext, final String... xmlRepresentation)
- throws Exception {
- final OutputStream output = new ByteArrayOutputStream();
- xmlBodyWriter.writeTo(normalizedNodeContext, null, null, null, mediaType, null, output);
-
- for (String element : xmlRepresentation) {
- assertTrue(output.toString().contains(element));
- }
- }
-
- private static NormalizedNodeContext prepareLeafrefData() {
- final QName cont = QName.create("basic:module", "2013-12-02", "cont");
- final QName lfBoolean = QName.create("basic:module", "2013-12-02", "lfBoolean");
- final QName lfLfref = QName.create("basic:module", "2013-12-02", "lfLfref");
-
- final DataSchemaNode contSchema = schemaContext.getDataChildByName(cont);
-
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> contData = SchemaAwareBuilders
- .containerBuilder((ContainerSchemaNode) contSchema);
-
- var instanceLf = ControllerContext
- .findInstanceDataChildrenByName((DataNodeContainer) contSchema, lfBoolean.getLocalName());
- DataSchemaNode schemaLf = instanceLf.get(0).child;
-
- contData.withChild(SchemaAwareBuilders.leafBuilder((LeafSchemaNode) schemaLf).withValue(Boolean.TRUE).build());
-
- instanceLf = ControllerContext.findInstanceDataChildrenByName((DataNodeContainer) contSchema,
- lfLfref.getLocalName());
- schemaLf = instanceLf.get(0).child;
-
- contData.withChild(SchemaAwareBuilders.leafBuilder((LeafSchemaNode) schemaLf).withValue("true").build());
-
- return new NormalizedNodeContext(
- InstanceIdentifierContext.ofStack(SchemaInferenceStack.ofDataTreePath(schemaContext, cont)),
- contData.build());
- }
-
- private static NormalizedNodeContext prepareLeafrefNegativeData() {
- final QName cont = QName.create("basic:module", "2013-12-02", "cont");
- final QName lfLfref = QName.create("basic:module", "2013-12-02", "lfLfrefNegative");
-
- final DataSchemaNode contSchema = schemaContext.getDataChildByName(cont);
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> contData = SchemaAwareBuilders
- .containerBuilder((ContainerSchemaNode) contSchema);
-
- final var instanceLf = ControllerContext.findInstanceDataChildrenByName((DataNodeContainer)
- contSchema, lfLfref.getLocalName());
- final DataSchemaNode schemaLf = instanceLf.get(0).child;
-
- contData.withChild(SchemaAwareBuilders.leafBuilder((LeafSchemaNode) schemaLf).withValue("value").build());
-
- return new NormalizedNodeContext(
- InstanceIdentifierContext.ofStack(SchemaInferenceStack.ofDataTreePath(schemaContext, cont)),
- contData.build());
- }
-
- private static NormalizedNodeContext prepareIdrefData(final String prefix, final boolean valueAsQName) {
- final QName cont = QName.create("basic:module", "2013-12-02", "cont");
- final QName cont1 = QName.create("basic:module", "2013-12-02", "cont1");
- final QName lf11 = QName.create("basic:module", "2013-12-02", "lf11");
-
- final DataSchemaNode contSchema = schemaContext.getDataChildByName(cont);
-
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> contData = SchemaAwareBuilders
- .containerBuilder((ContainerSchemaNode) contSchema);
-
- final DataSchemaNode cont1Schema = ((ContainerSchemaNode) contSchema).getDataChildByName(cont1);
-
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> cont1Data = SchemaAwareBuilders
- .containerBuilder((ContainerSchemaNode) cont1Schema);
-
- Object value = null;
- if (valueAsQName) {
- value = QName.create("referenced:module", "2013-12-02", "iden");
- } else {
- value = "no qname value";
- }
-
- final var instanceLf = ControllerContext
- .findInstanceDataChildrenByName((DataNodeContainer) cont1Schema, lf11.getLocalName());
- final DataSchemaNode schemaLf = instanceLf.get(0).child;
-
- cont1Data.withChild(SchemaAwareBuilders.leafBuilder((LeafSchemaNode) schemaLf).withValue(value).build());
-
- contData.withChild(cont1Data.build());
-
- final NormalizedNodeContext testNormalizedNodeContext = new NormalizedNodeContext(
- InstanceIdentifierContext.ofStack(SchemaInferenceStack.ofDataTreePath(schemaContext, cont)),
- contData.build());
- return testNormalizedNodeContext;
- }
-
- @Override
- protected MediaType getMediaType() {
- return null;
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.nn.to.xml.test;
-
-import static org.junit.Assert.assertTrue;
-
-import java.io.ByteArrayOutputStream;
-import java.io.OutputStream;
-import javax.ws.rs.core.MediaType;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.sal.rest.impl.test.providers.AbstractBodyReaderTest;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeXmlBodyWriter;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.SchemaAwareBuilders;
-import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
-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.util.SchemaInferenceStack;
-
-public class NnToXmlWithChoiceTest extends AbstractBodyReaderTest {
-
- private final NormalizedNodeXmlBodyWriter xmlBodyWriter;
- private static EffectiveModelContext schemaContext;
-
- public NnToXmlWithChoiceTest() {
- super(schemaContext, null);
- xmlBodyWriter = new NormalizedNodeXmlBodyWriter();
- }
-
- @BeforeClass
- public static void initialization() {
- schemaContext = schemaContextLoader("/nn-to-xml/choice", schemaContext);
- }
-
- @Test
- public void cnSnToXmlWithYangChoice() throws Exception {
- NormalizedNodeContext normalizedNodeContext = prepareNNC("lf1",
- "String data1");
- OutputStream output = new ByteArrayOutputStream();
- xmlBodyWriter.writeTo(normalizedNodeContext, null, null, null,
- mediaType, null, output);
- assertTrue(output.toString().contains("<lf1>String data1</lf1>"));
-
- normalizedNodeContext = prepareNNC("lf2", "String data2");
- output = new ByteArrayOutputStream();
-
- xmlBodyWriter.writeTo(normalizedNodeContext, null, null, null,
- mediaType, null, output);
- assertTrue(output.toString().contains("<lf2>String data2</lf2>"));
- }
-
- private static NormalizedNodeContext prepareNNC(final String name, final Object value) {
-
- final QName contQname = QName.create("module:with:choice", "2013-12-18",
- "cont");
- final QName lf = QName.create("module:with:choice", "2013-12-18", name);
- final QName choA = QName.create("module:with:choice", "2013-12-18", "choA");
-
- final DataSchemaNode contSchemaNode = schemaContext
- .getDataChildByName(contQname);
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> dataContainerNodeAttrBuilder = SchemaAwareBuilders
- .containerBuilder((ContainerSchemaNode) contSchemaNode);
-
- final DataSchemaNode choiceSchemaNode = ((ContainerSchemaNode) contSchemaNode)
- .getDataChildByName(choA);
- assertTrue(choiceSchemaNode instanceof ChoiceSchemaNode);
-
- final DataContainerNodeBuilder<NodeIdentifier, ChoiceNode> dataChoice = SchemaAwareBuilders
- .choiceBuilder((ChoiceSchemaNode) choiceSchemaNode);
-
- final var instanceLf = ControllerContext
- .findInstanceDataChildrenByName(
- (DataNodeContainer) contSchemaNode, lf.getLocalName());
- final DataSchemaNode schemaLf = instanceLf.get(0).child;
-
- dataChoice.withChild(SchemaAwareBuilders.leafBuilder((LeafSchemaNode) schemaLf)
- .withValue(value).build());
-
- dataContainerNodeAttrBuilder.withChild(dataChoice.build());
-
- final NormalizedNodeContext testNormalizedNodeContext = new NormalizedNodeContext(
- InstanceIdentifierContext.ofStack(SchemaInferenceStack.ofDataTreePath(schemaContext, contQname)),
- dataContainerNodeAttrBuilder.build());
-
- return testNormalizedNodeContext;
- }
-
- @Override
- protected MediaType getMediaType() {
- return null;
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.nn.to.xml.test;
-
-import static org.junit.Assert.assertTrue;
-
-import com.google.common.base.Preconditions;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.net.URISyntaxException;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.sal.rest.impl.test.providers.AbstractBodyReaderTest;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeXmlBodyWriter;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.SchemaAwareBuilders;
-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;
-
-public class NnToXmlWithDataFromSeveralModulesTest extends
- AbstractBodyReaderTest {
-
- private final NormalizedNodeXmlBodyWriter xmlBodyWriter;
- private static EffectiveModelContext schemaContext;
-
- public NnToXmlWithDataFromSeveralModulesTest() {
- super(schemaContext, null);
- xmlBodyWriter = new NormalizedNodeXmlBodyWriter();
- }
-
- @BeforeClass
- public static void initialize() {
- schemaContext = schemaContextLoader("/nn-to-xml/data-of-several-modules/yang", schemaContext);
- }
-
- @Test
- public void dataFromSeveralModulesToXmlTest()
- throws WebApplicationException, IOException, URISyntaxException {
- final NormalizedNodeContext normalizedNodeContext = prepareNormalizedNodeContext();
- final OutputStream output = new ByteArrayOutputStream();
- xmlBodyWriter.writeTo(normalizedNodeContext, null, null, null,
- mediaType, null, output);
-
- final String outputString = output.toString();
- // data
- assertTrue(outputString
- .contains(
- "<data xmlns=" + '"'
- + "urn:ietf:params:xml:ns:netconf:base:1.0"
- + '"' + '>'));
- // cont m2
- assertTrue(outputString.contains(
- "<cont_m2 xmlns=" + '"' + "module:two" + '"' + '>'));
- assertTrue(outputString.contains("<lf1_m2>lf1 m2 value</lf1_m2>"));
- assertTrue(outputString.contains("<contB_m2/>"));
- assertTrue(outputString.contains("</cont_m2>"));
-
- // cont m1
- assertTrue(outputString.contains(
- "<cont_m1 xmlns=" + '"' + "module:one" + '"' + '>'));
- assertTrue(outputString.contains("<contB_m1/>"));
- assertTrue(outputString.contains("<lf1_m1>lf1 m1 value</lf1_m1>"));
- assertTrue(outputString.contains("</cont_m1>"));
-
- // end
- assertTrue(output.toString().contains("</data>"));
- }
-
- @Override
- protected MediaType getMediaType() {
- // TODO Auto-generated method stub
- return null;
- }
-
- private static NormalizedNodeContext prepareNormalizedNodeContext() {
- final String rev = "2014-01-17";
-
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> dataContSchemaContNode = SchemaAwareBuilders
- .containerBuilder(schemaContext);
-
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> modul1 = buildContBuilderMod1(
- "module:one", rev, "cont_m1", "contB_m1", "lf1_m1",
- "lf1 m1 value");
- dataContSchemaContNode.withChild(modul1.build());
-
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> modul2 = buildContBuilderMod1(
- "module:two", rev, "cont_m2", "contB_m2", "lf1_m2",
- "lf1 m2 value");
- dataContSchemaContNode.withChild(modul2.build());
-
- final NormalizedNodeContext testNormalizedNodeContext = new NormalizedNodeContext(
- InstanceIdentifierContext.ofLocalRoot(schemaContext),
- dataContSchemaContNode.build());
-
- return testNormalizedNodeContext;
- }
-
- private static DataContainerNodeBuilder<NodeIdentifier, ContainerNode> buildContBuilderMod1(
- final String uri, final String rev, final String cont, final String contB, final String lf1,
- final String lf1Value) {
- final QName contQname = QName.create(uri, rev, cont);
- final QName contBQname = QName.create(uri, rev, contB);
- final QName lf1Qname = QName.create(contQname, lf1);
-
- final DataSchemaNode contSchemaNode = schemaContext
- .getDataChildByName(contQname);
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> dataContainerNodeAttrBuilder = SchemaAwareBuilders
- .containerBuilder((ContainerSchemaNode) contSchemaNode);
-
- Preconditions.checkState(contSchemaNode instanceof ContainerSchemaNode);
- final var instanceLf1_m1 = ControllerContext.findInstanceDataChildrenByName(
- (DataNodeContainer) contSchemaNode, lf1Qname.getLocalName());
- final DataSchemaNode schemaLf1_m1 = instanceLf1_m1.get(0).child;
-
- dataContainerNodeAttrBuilder.withChild(SchemaAwareBuilders
- .leafBuilder((LeafSchemaNode) schemaLf1_m1)
- .withValue(lf1Value).build());
-
- final DataSchemaNode contBSchemaNode = ((ContainerSchemaNode) contSchemaNode)
- .getDataChildByName(contBQname);
-
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> dataContainerB = SchemaAwareBuilders
- .containerBuilder((ContainerSchemaNode) contBSchemaNode);
-
- return dataContainerNodeAttrBuilder.withChild(dataContainerB.build());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2019 Red Hat, 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.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertEquals;
-
-import com.google.inject.AbstractModule;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import javax.inject.Inject;
-import org.junit.Rule;
-import org.junit.Test;
-import org.opendaylight.aaa.filterchain.configuration.CustomFilterAdapterConfiguration;
-import org.opendaylight.aaa.web.WebServer;
-import org.opendaylight.aaa.web.testutils.TestWebClient;
-import org.opendaylight.aaa.web.testutils.WebTestModule;
-import org.opendaylight.controller.sal.restconf.impl.test.incubate.InMemoryMdsalModule;
-import org.opendaylight.infrautils.inject.guice.testutils.AnnotationsModule;
-import org.opendaylight.infrautils.inject.guice.testutils.GuiceRule;
-import org.opendaylight.netconf.sal.restconf.api.RestConfConfig;
-import org.opendaylight.netconf.sal.restconf.impl.Bierman02RestConfWiring;
-
-/**
- * Tests if the {@link Bierman02RestConfWiring} works.
- *
- * @author Michael Vorburger.ch
- */
-public class Bierman02RestConfWiringTest {
-
- public static class TestModule extends AbstractModule {
- @Override
- protected void configure() {
- bind(Bierman02RestConfWiring.class).asEagerSingleton();
- bind(RestConfConfig.class).toInstance(() -> 9090);
- bind(CustomFilterAdapterConfiguration.class).toInstance(listener -> { });
- }
- }
-
- public @Rule GuiceRule guice = new GuiceRule(TestModule.class,
- InMemoryMdsalModule.class, WebTestModule.class, AnnotationsModule.class);
-
- @Inject WebServer webServer;
- @Inject TestWebClient webClient;
-
- @Test
- public void testWiring() throws IOException, InterruptedException, URISyntaxException {
- assertEquals(200, webClient.request("GET", "/restconf/modules/").statusCode());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 Brocade Communications 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.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateBooleanFluentFuture;
-import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFailedFluentFuture;
-import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFluentFuture;
-import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateTrueFluentFuture;
-
-import com.google.common.collect.ImmutableClassToInstanceMap;
-import com.google.common.util.concurrent.FluentFuture;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.List;
-import java.util.Optional;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.junit.MockitoJUnitRunner;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.common.api.ReadFailedException;
-import org.opendaylight.mdsal.dom.api.DOMDataBroker;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeService;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
-import org.opendaylight.mdsal.dom.api.DOMMountPoint;
-import org.opendaylight.mdsal.dom.api.DOMNotificationService;
-import org.opendaylight.mdsal.dom.api.DOMRpcResult;
-import org.opendaylight.mdsal.dom.api.DOMRpcService;
-import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
-import org.opendaylight.netconf.sal.restconf.impl.BrokerFacade;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.netconf.sal.restconf.impl.PutResult;
-import org.opendaylight.netconf.sal.streams.listeners.ListenerAdapter;
-import org.opendaylight.netconf.sal.streams.listeners.NotificationListenerAdapter;
-import org.opendaylight.netconf.sal.streams.listeners.Notificator;
-import org.opendaylight.restconf.common.ErrorTags;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.errors.RestconfError;
-import org.opendaylight.restconf.common.patch.PatchContext;
-import org.opendaylight.restconf.common.patch.PatchStatusContext;
-import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.CreateDataChangeEventSubscriptionInput1.Scope;
-import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping.NotificationOutputType;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.common.ErrorType;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
-
-/**
- * Unit tests for BrokerFacade.
- *
- * @author Thomas Pantelis
- */
-@RunWith(MockitoJUnitRunner.StrictStubs.class)
-public class BrokerFacadeTest {
-
- @Mock
- private DOMDataBroker domDataBroker;
- @Mock
- private DOMNotificationService domNotification;
- @Mock
- private DOMRpcService mockRpcService;
- @Mock
- private DOMMountPoint mockMountInstance;
- @Mock
- private DOMDataTreeReadTransaction readTransaction;
- @Mock
- private DOMDataTreeWriteTransaction writeTransaction;
- @Mock
- private DOMDataTreeReadWriteTransaction rwTransaction;
-
- private BrokerFacade brokerFacade;
- private final NormalizedNode dummyNode = createDummyNode("test:module", "2014-01-09", "interfaces");
- private final FluentFuture<Optional<NormalizedNode>> dummyNodeInFuture = wrapDummyNode(dummyNode);
- private final QName qname = TestUtils.buildQName("interfaces","test:module", "2014-01-09");
- private final YangInstanceIdentifier instanceID = YangInstanceIdentifier.builder().node(qname).build();
- private ControllerContext controllerContext;
-
- @Before
- public void setUp() throws Exception {
- controllerContext = TestRestconfUtils.newControllerContext(
- TestUtils.loadSchemaContext("/full-versions/test-module", "/modules"));
-
- brokerFacade = BrokerFacade.newInstance(mockRpcService, domDataBroker, domNotification, controllerContext);
-
- when(domDataBroker.newReadOnlyTransaction()).thenReturn(readTransaction);
- when(domDataBroker.newReadWriteTransaction()).thenReturn(rwTransaction);
- when(domDataBroker.getExtensions()).thenReturn(ImmutableClassToInstanceMap.of(
- DOMDataTreeChangeService.class, Mockito.mock(DOMDataTreeChangeService.class)));
- }
-
- private static FluentFuture<Optional<NormalizedNode>> wrapDummyNode(final NormalizedNode dummyNode) {
- return immediateFluentFuture(Optional.of(dummyNode));
- }
-
- private static FluentFuture<Boolean> wrapExistence(final boolean exists) {
- return immediateBooleanFluentFuture(exists);
- }
-
- /**
- * Value of this node shouldn't be important for testing purposes.
- */
- private static NormalizedNode createDummyNode(final String namespace, final String date, final String localName) {
- return Builders.containerBuilder()
- .withNodeIdentifier(new NodeIdentifier(QName.create(namespace, date, localName)))
- .build();
- }
-
- @Test
- public void testReadConfigurationData() {
- when(readTransaction.read(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class))).thenReturn(
- dummyNodeInFuture);
-
- final NormalizedNode actualNode = brokerFacade.readConfigurationData(instanceID);
-
- assertSame("readConfigurationData", dummyNode, actualNode);
- }
-
- @Test
- public void testReadOperationalData() {
- when(readTransaction.read(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class))).thenReturn(
- dummyNodeInFuture);
-
- final NormalizedNode actualNode = brokerFacade.readOperationalData(instanceID);
-
- assertSame("readOperationalData", dummyNode, actualNode);
- }
-
- @Test
- public void test503() throws Exception {
- final RpcError error = RpcResultBuilder.newError(ErrorType.TRANSPORT, ErrorTag.RESOURCE_DENIED,
- "Master is down. Please try again.");
- doReturn(immediateFailedFluentFuture(new ReadFailedException("Read from transaction failed", error)))
- .when(readTransaction).read(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class));
-
- final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
- () -> brokerFacade.readConfigurationData(instanceID, "explicit"));
- final List<RestconfError> errors = ex.getErrors();
- assertEquals(1, errors.size());
- assertEquals("getErrorTag", ErrorTags.RESOURCE_DENIED_TRANSPORT, errors.get(0).getErrorTag());
- assertEquals("getErrorType", ErrorType.TRANSPORT,errors.get(0).getErrorType());
- assertEquals("getErrorMessage", "Master is down. Please try again.", errors.get(0).getErrorMessage());
- }
-
- @Test
- public void testInvokeRpc() throws Exception {
- final DOMRpcResult expResult = mock(DOMRpcResult.class);
- doReturn(immediateFluentFuture(expResult)).when(mockRpcService).invokeRpc(qname, dummyNode);
-
- final ListenableFuture<? extends DOMRpcResult> actualFuture = brokerFacade.invokeRpc(qname,
- dummyNode);
- assertNotNull("Future is null", actualFuture);
- final DOMRpcResult actualResult = actualFuture.get();
- assertSame("invokeRpc", expResult, actualResult);
- }
-
- @Test
- public void testCommitConfigurationDataPut() throws Exception {
- doReturn(CommitInfo.emptyFluentFuture()).when(rwTransaction).commit();
-
- doReturn(immediateFluentFuture(Optional.of(mock(NormalizedNode.class)))).when(rwTransaction)
- .read(LogicalDatastoreType.CONFIGURATION, instanceID);
-
- final PutResult result = brokerFacade.commitConfigurationDataPut(mock(EffectiveModelContext.class),
- instanceID, dummyNode, null, null);
-
- assertSame("commitConfigurationDataPut", CommitInfo.emptyFluentFuture(), result.getFutureOfPutData());
-
- final InOrder inOrder = inOrder(domDataBroker, rwTransaction);
- inOrder.verify(domDataBroker).newReadWriteTransaction();
- inOrder.verify(rwTransaction).put(LogicalDatastoreType.CONFIGURATION, instanceID, dummyNode);
- inOrder.verify(rwTransaction).commit();
- }
-
- @Test
- public void testCommitConfigurationDataPost() {
- when(rwTransaction.exists(LogicalDatastoreType.CONFIGURATION, instanceID))
- .thenReturn(wrapExistence(false));
-
- doReturn(CommitInfo.emptyFluentFuture()).when(rwTransaction).commit();
-
- final FluentFuture<? extends CommitInfo> actualFuture = brokerFacade
- .commitConfigurationDataPost(mock(EffectiveModelContext.class), instanceID, dummyNode, null,
- null);
-
- assertSame("commitConfigurationDataPost", CommitInfo.emptyFluentFuture(), actualFuture);
-
- final InOrder inOrder = inOrder(domDataBroker, rwTransaction);
- inOrder.verify(domDataBroker).newReadWriteTransaction();
- inOrder.verify(rwTransaction).exists(LogicalDatastoreType.CONFIGURATION, instanceID);
- inOrder.verify(rwTransaction).put(LogicalDatastoreType.CONFIGURATION, instanceID, dummyNode);
- inOrder.verify(rwTransaction).commit();
- }
-
- @Test(expected = RestconfDocumentedException.class)
- public void testCommitConfigurationDataPostAlreadyExists() {
- when(rwTransaction.exists(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class)))
- .thenReturn(immediateTrueFluentFuture());
- try {
- // Schema context is only necessary for ensuring parent structure
- brokerFacade.commitConfigurationDataPost((EffectiveModelContext) null, instanceID, dummyNode,
- null, null);
- } catch (final RestconfDocumentedException e) {
- assertEquals("getErrorTag", ErrorTag.DATA_EXISTS, e.getErrors().get(0).getErrorTag());
- throw e;
- }
- }
-
- /**
- * Positive test of delete operation when data to delete exits. Returned value and order of steps are validated.
- */
- @Test
- public void testCommitConfigurationDataDelete() throws Exception {
- // assume that data to delete exists
- prepareDataForDelete(true);
-
- // expected result
- doReturn(CommitInfo.emptyFluentFuture()).when(rwTransaction).commit();
-
- // test
- final FluentFuture<? extends CommitInfo> actualFuture = brokerFacade
- .commitConfigurationDataDelete(instanceID);
-
- // verify result and interactions
- assertSame("commitConfigurationDataDelete", CommitInfo.emptyFluentFuture(), actualFuture);
-
- // check exists, delete, submit
- final InOrder inOrder = inOrder(domDataBroker, rwTransaction);
- inOrder.verify(rwTransaction).exists(LogicalDatastoreType.CONFIGURATION, instanceID);
- inOrder.verify(rwTransaction).delete(LogicalDatastoreType.CONFIGURATION, instanceID);
- inOrder.verify(rwTransaction).commit();
- }
-
- /**
- * Negative test of delete operation when data to delete does not exist. Error DATA_MISSING should be returned.
- */
- @Test
- public void testCommitConfigurationDataDeleteNoData() throws Exception {
- // assume that data to delete does not exist
- prepareDataForDelete(false);
-
- // try to delete and expect DATA_MISSING error
- final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
- () -> brokerFacade.commitConfigurationDataDelete(instanceID));
- final List<RestconfError> errors = ex.getErrors();
- assertEquals(1, errors.size());
- assertEquals(ErrorType.PROTOCOL, errors.get(0).getErrorType());
- assertEquals(ErrorTag.DATA_MISSING, errors.get(0).getErrorTag());
- }
-
- /**
- * Prepare conditions to test delete operation. Data to delete exists or does not exist according to value of
- * {@code assumeDataExists} parameter.
- * @param assumeDataExists boolean to assume if data exists
- */
- private void prepareDataForDelete(final boolean assumeDataExists) {
- when(rwTransaction.exists(LogicalDatastoreType.CONFIGURATION, instanceID))
- .thenReturn(immediateBooleanFluentFuture(assumeDataExists));
- }
-
- @Test
- public void testRegisterToListenDataChanges() {
- final ListenerAdapter listener = Notificator.createListener(instanceID, "stream",
- NotificationOutputType.XML, controllerContext);
-
- @SuppressWarnings("unchecked")
- final ListenerRegistration<ListenerAdapter> mockRegistration = mock(ListenerRegistration.class);
-
- DOMDataTreeChangeService changeService = domDataBroker.getExtensions()
- .getInstance(DOMDataTreeChangeService.class);
- DOMDataTreeIdentifier loc = new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, instanceID);
- when(changeService.registerDataTreeChangeListener(eq(loc), eq(listener))).thenReturn(mockRegistration);
-
- brokerFacade.registerToListenDataChanges(LogicalDatastoreType.CONFIGURATION, Scope.BASE, listener);
-
- verify(changeService).registerDataTreeChangeListener(loc, listener);
-
- assertEquals("isListening", true, listener.isListening());
-
- brokerFacade.registerToListenDataChanges(LogicalDatastoreType.CONFIGURATION, Scope.BASE, listener);
- verifyNoMoreInteractions(changeService);
- }
-
- /**
- * Create, register, close and remove notification listener.
- */
- @Test
- public void testRegisterToListenNotificationChanges() throws Exception {
- // create test notification listener
- final String identifier = "create-notification-stream/toaster:toastDone";
- Notificator.createNotificationListener(
- List.of(Absolute.of(QName.create("http://netconfcentral.org/ns/toaster", "2009-11-20", "toastDone"))),
- identifier, "XML", controllerContext);
- final NotificationListenerAdapter listener = Notificator.getNotificationListenerFor(identifier).get(0);
-
- // mock registration
- final ListenerRegistration<NotificationListenerAdapter> registration = mock(ListenerRegistration.class);
- when(domNotification.registerNotificationListener(listener, listener.getSchemaPath()))
- .thenReturn(registration);
-
- // test to register listener for the first time
- brokerFacade.registerToListenNotification(listener);
- assertEquals("Registration was not successful", true, listener.isListening());
-
- // try to register for the second time
- brokerFacade.registerToListenNotification(listener);
- assertEquals("Registration was not successful", true, listener.isListening());
-
- // registrations should be invoked only once
- verify(domNotification, times(1)).registerNotificationListener(listener, listener.getSchemaPath());
-
- final DOMTransactionChain transactionChain = mock(DOMTransactionChain.class);
- final DOMDataTreeWriteTransaction wTx = mock(DOMDataTreeWriteTransaction.class);
- // close and remove test notification listener
- listener.close();
- Notificator.removeListenerIfNoSubscriberExists(listener);
- }
-
- /**
- * Test Patch method on the server with no data.
- */
- @Test
- public void testPatchConfigurationDataWithinTransactionServer() throws Exception {
- final PatchContext patchContext = mock(PatchContext.class);
-
- when(patchContext.getData()).thenReturn(List.of());
- // no mount point
- doReturn(InstanceIdentifierContext.ofPath(SchemaInferenceStack.of(mock(EffectiveModelContext.class)),
- mock(DataSchemaNode.class), YangInstanceIdentifier.empty(), null))
- .when(patchContext).getInstanceIdentifierContext();
-
- doReturn(CommitInfo.emptyFluentFuture()).when(rwTransaction).commit();
-
- final PatchStatusContext status = brokerFacade.patchConfigurationDataWithinTransaction(patchContext);
-
- // assert success
- assertTrue("Patch operation should be successful on server", status.isOk());
- }
-
- /**
- * Test Patch method on mounted device with no data.
- */
- @Test
- public void testPatchConfigurationDataWithinTransactionMount() throws Exception {
- final PatchContext patchContext = mock(PatchContext.class);
- final DOMMountPoint mountPoint = mock(DOMMountPoint.class);
- final DOMDataBroker mountDataBroker = mock(DOMDataBroker.class);
- final DOMDataTreeReadWriteTransaction transaction = mock(DOMDataTreeReadWriteTransaction.class);
-
- when(patchContext.getData()).thenReturn(List.of());
- // return mount point with broker
- doReturn(InstanceIdentifierContext.ofPath(SchemaInferenceStack.of(mock(EffectiveModelContext.class)),
- mock(DataSchemaNode.class), YangInstanceIdentifier.empty(), mountPoint))
- .when(patchContext).getInstanceIdentifierContext();
-
- when(mountPoint.getService(DOMDataBroker.class)).thenReturn(Optional.of(mountDataBroker));
- when(mountPoint.getService(DOMSchemaService.class)).thenReturn(Optional.empty());
- when(mountDataBroker.newReadWriteTransaction()).thenReturn(transaction);
- doReturn(CommitInfo.emptyFluentFuture()).when(transaction).commit();
-
- final PatchStatusContext status = brokerFacade.patchConfigurationDataWithinTransaction(patchContext);
-
- // assert success
- assertTrue("Patch operation should be successful on mounted device", status.isOk());
- }
-
- /**
- * Negative test for Patch operation when mounted device does not support {@link DOMDataBroker service.}
- * Patch operation should fail with global error.
- */
- @Test
- public void testPatchConfigurationDataWithinTransactionMountFail() throws Exception {
- final PatchContext patchContext = mock(PatchContext.class);
- final DOMMountPoint mountPoint = mock(DOMMountPoint.class);
-
- doReturn(InstanceIdentifierContext.ofPath(SchemaInferenceStack.of(mock(EffectiveModelContext.class)),
- mock(DataSchemaNode.class), YangInstanceIdentifier.empty(), mountPoint))
- .when(patchContext).getInstanceIdentifierContext();
-
- // missing broker on mounted device
- when(mountPoint.getService(DOMDataBroker.class)).thenReturn(Optional.empty());
- when(mountPoint.getService(DOMSchemaService.class)).thenReturn(Optional.empty());
-
- final PatchStatusContext status = brokerFacade.patchConfigurationDataWithinTransaction(patchContext);
-
- // assert not successful operation with error
- assertNotNull(status.getGlobalErrors());
- assertEquals(1, status.getGlobalErrors().size());
- assertEquals(ErrorType.APPLICATION, status.getGlobalErrors().get(0).getErrorType());
- assertEquals(ErrorTag.OPERATION_FAILED, status.getGlobalErrors().get(0).getErrorTag());
-
- assertFalse("Patch operation should fail on mounted device without Broker", status.isOk());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import java.io.FileNotFoundException;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.Module;
-
-public class Bug3595Test {
-
- private static final QName CONT_QNAME = QName.create("leafref:module", "2014-04-17", "cont");
- private static final QName LST_WITH_LFREF_KEY_QNAME = QName.create(CONT_QNAME, "lst-with-lfref-key");
- private static final QName LFREF_KEY_QNAME = QName.create(CONT_QNAME, "lfref-key");
- private static EffectiveModelContext schemaContext;
-
- private final ControllerContext controllerContext = TestRestconfUtils.newControllerContext(schemaContext);
-
- @BeforeClass
- public static void initialize() throws FileNotFoundException {
- schemaContext = TestUtils.loadSchemaContext("/leafref/yang");
- Module module = TestUtils.findModule(schemaContext.getModules(), "leafref-module");
- assertNotNull(module);
- module = TestUtils.findModule(schemaContext.getModules(), "referenced-module");
- assertNotNull(module);
- }
-
- @Test
- public void testLeafrefListKeyDeserializtion() {
- final YangInstanceIdentifier node1IIexpected = YangInstanceIdentifier.of(CONT_QNAME)
- .node(LST_WITH_LFREF_KEY_QNAME).node(NodeIdentifierWithPredicates.of(
- LST_WITH_LFREF_KEY_QNAME, LFREF_KEY_QNAME, "node1"));
- final InstanceIdentifierContext iiContext =
- controllerContext.toInstanceIdentifier("leafref-module:cont/lst-with-lfref-key/node1");
- iiContext.getInstanceIdentifier();
- assertEquals(node1IIexpected, iiContext.getInstanceIdentifier());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 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.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import java.io.FileNotFoundException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.mdsal.dom.api.DOMMountPoint;
-import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
-
-public class Bug8072Test {
- private static final String EXTERNAL_MODULE_NAME = "test-module";
- private static final QName MODULES_QNAME = QName.create("test:module", "2014-01-09", "modules");
- private static final QName MODULE_QNAME = QName.create("test:module", "2014-01-09", "module");
- private static final QName NAME_QNAME = QName.create("test:module", "2014-01-09", "name");
- private static final QName TYPE_QNAME = QName.create("test:module", "2014-01-09", "type");
- private static final QName MODULE_TYPE_QNAME = QName.create("test:module", "2014-01-09", "module-type");
-
- private static EffectiveModelContext schemaContext;
-
- private final ControllerContext controllerContext;
-
- public Bug8072Test() throws FileNotFoundException {
- final EffectiveModelContext mountPointContext = TestUtils.loadSchemaContext("/full-versions/test-module");
- final DOMMountPoint mountInstance = mock(DOMMountPoint.class);
- controllerContext = TestRestconfUtils.newControllerContext(schemaContext, mountInstance);
- doReturn(Optional.of(FixedDOMSchemaService.of(() -> mountPointContext))).when(mountInstance)
- .getService(DOMSchemaService.class);
- }
-
- @BeforeClass
- public static void init() throws FileNotFoundException, ReactorException {
- schemaContext = TestUtils.loadSchemaContext("/full-versions/yangs");
- assertEquals(0, schemaContext.findModules(EXTERNAL_MODULE_NAME).size());
- }
-
- @Test
- public void testIdentityRefFromExternalModule() throws FileNotFoundException, ReactorException {
- final InstanceIdentifierContext ctx = controllerContext.toInstanceIdentifier(
- "simple-nodes:users/yang-ext:mount/test-module:modules/module/test-module:module-type/name");
-
- final Map<QName, Object> keyValues = new HashMap<>();
- keyValues.put(NAME_QNAME, "name");
- keyValues.put(TYPE_QNAME, MODULE_TYPE_QNAME);
- final YangInstanceIdentifier expectedYII = YangInstanceIdentifier.of(MODULES_QNAME).node(MODULE_QNAME)
- .node(NodeIdentifierWithPredicates.of(MODULE_QNAME, keyValues));
-
- assertEquals(expectedYII, ctx.getInstanceIdentifier());
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.ByteArrayInputStream;
-import java.io.FileNotFoundException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import javax.xml.stream.XMLEventReader;
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.events.StartElement;
-import javax.xml.stream.events.XMLEvent;
-import org.junit.BeforeClass;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
-
-public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSchemaLoader {
-
- @BeforeClass
- public static void initialize() throws FileNotFoundException, ReactorException {
- dataLoad("/instanceidentifier/yang", 4, "instance-identifier-module", "cont");
- }
-
-
- private static void validateXmlOutput(final String xml) throws XMLStreamException {
- final XMLInputFactory xmlInFactory = XMLInputFactory.newInstance();
- XMLEventReader eventReader;
-
- eventReader = xmlInFactory.createXMLEventReader(new ByteArrayInputStream(xml.getBytes()));
- String augmentAugmentModulePrefix = null;
- String augmentModulePrefix = null;
- String instanceIdentifierModulePrefix = null;
- while (eventReader.hasNext()) {
- final XMLEvent nextEvent = eventReader.nextEvent();
- if (nextEvent.isStartElement()) {
- final StartElement startElement = (StartElement) nextEvent;
- if (startElement.getName().getLocalPart().equals("lf111")) {
- final Iterator<?> prefixes =
- startElement.getNamespaceContext().getPrefixes("augment:augment:module");
-
- while (prefixes.hasNext() && augmentAugmentModulePrefix == null) {
- final String prefix = (String) prefixes.next();
- if (!prefix.isEmpty()) {
- augmentAugmentModulePrefix = prefix;
- }
- }
-
- augmentModulePrefix = startElement.getNamespaceContext().getPrefix("augment:module");
- instanceIdentifierModulePrefix =
- startElement.getNamespaceContext().getPrefix("instance:identifier:module");
- break;
- }
- }
- }
-
- assertNotNull(augmentAugmentModulePrefix);
- assertNotNull(augmentModulePrefix);
- assertNotNull(instanceIdentifierModulePrefix);
-
- final String instanceIdentifierValue = "/" + instanceIdentifierModulePrefix + ":cont/"
- + instanceIdentifierModulePrefix + ":cont1/" + augmentModulePrefix + ":lst11[" + augmentModulePrefix
- + ":keyvalue111='value1'][" + augmentModulePrefix + ":keyvalue112='value2']/"
- + augmentAugmentModulePrefix + ":lf112";
-
- assertTrue(xml.contains(instanceIdentifierValue));
-
- }
-
- private static void validateXmlOutputWithLeafList(final String xml) throws XMLStreamException {
- final XMLInputFactory xmlInFactory = XMLInputFactory.newInstance();
- XMLEventReader eventReader;
-
- eventReader = xmlInFactory.createXMLEventReader(new ByteArrayInputStream(xml.getBytes()));
- String augmentModuleLfLstPrefix = null;
- String iiModulePrefix = null;
- while (eventReader.hasNext()) {
- final XMLEvent nextEvent = eventReader.nextEvent();
- if (nextEvent.isStartElement()) {
- final StartElement startElement = (StartElement) nextEvent;
- if (startElement.getName().getLocalPart().equals("lf111")) {
- final Iterator<?> prefixes =
- startElement.getNamespaceContext().getPrefixes("augment:module:leaf:list");
-
- while (prefixes.hasNext() && augmentModuleLfLstPrefix == null) {
- final String prefix = (String) prefixes.next();
- if (!prefix.isEmpty()) {
- augmentModuleLfLstPrefix = prefix;
- }
- }
- iiModulePrefix = startElement.getNamespaceContext().getPrefix("instance:identifier:module");
- break;
- }
- }
- }
-
- assertNotNull(augmentModuleLfLstPrefix);
- assertNotNull(iiModulePrefix);
-
- final String instanceIdentifierValue = "/" + iiModulePrefix + ":cont/" + iiModulePrefix + ":cont1/"
- + augmentModuleLfLstPrefix + ":lflst11[.='lflst11_1']";
-
- assertTrue(xml.contains(instanceIdentifierValue));
-
- }
-
- private static YangInstanceIdentifier createInstanceIdentifier() {
- final List<PathArgument> pathArguments = new ArrayList<>();
- pathArguments.add(new NodeIdentifier(QName.create("instance:identifier:module", "cont")));
- pathArguments.add(new NodeIdentifier(QName.create("instance:identifier:module", "cont1")));
-
- final QName qName = QName.create("augment:module", "lst11");
- final Map<QName, Object> keyValues = new HashMap<>();
- keyValues.put(QName.create("augment:module", "keyvalue111"), "value1");
- keyValues.put(QName.create("augment:module", "keyvalue112"), "value2");
- final NodeIdentifierWithPredicates nodeIdentifierWithPredicates =
- NodeIdentifierWithPredicates.of(qName, keyValues);
- pathArguments.add(nodeIdentifierWithPredicates);
-
- pathArguments.add(new NodeIdentifier(QName.create("augment:augment:module", "lf112")));
-
- return YangInstanceIdentifier.create(pathArguments);
- }
-
- private static YangInstanceIdentifier createInstanceIdentifierWithLeafList() {
- final List<PathArgument> pathArguments = new ArrayList<>();
- pathArguments.add(new NodeIdentifier(QName.create("instance:identifier:module", "cont")));
- pathArguments.add(new NodeIdentifier(QName.create("instance:identifier:module", "cont1")));
- pathArguments.add(new NodeWithValue<>(QName.create("augment:module:leaf:list", "lflst11"), "lflst11_1"));
-
- return YangInstanceIdentifier.create(pathArguments);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 Brocade Communication Systems, Inc., 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.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-
-import java.io.FileNotFoundException;
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeJsonBodyWriter;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeXmlBodyWriter;
-import org.opendaylight.netconf.sal.rest.impl.XmlNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.restconf.impl.BrokerFacade;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.netconf.sal.restconf.impl.RestconfImpl;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
-
-public class CodecsExceptionsCatchingTest extends JerseyTest {
-
- private RestconfImpl restConf;
- private ControllerContext controllerContext;
-
- @Before
- public void init() throws FileNotFoundException, ReactorException {
- restConf = RestconfImpl.newInstance(mock(BrokerFacade.class), controllerContext);
- controllerContext = TestRestconfUtils.newControllerContext(TestUtils.loadSchemaContext(
- "/decoding-exception/yang"));
- }
-
- @Override
- protected Application configure() {
- /* enable/disable Jersey logs to console */
- // enable(TestProperties.LOG_TRAFFIC);
- // enable(TestProperties.DUMP_ENTITY);
- // enable(TestProperties.RECORD_LOG_LEVEL);
- // set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
- ResourceConfig resourceConfig = new ResourceConfig();
- resourceConfig = resourceConfig.registerInstances(restConf, new NormalizedNodeJsonBodyWriter(),
- new NormalizedNodeXmlBodyWriter(), new XmlNormalizedNodeBodyReader(controllerContext),
- new JsonNormalizedNodeBodyReader(controllerContext));
- return resourceConfig;
- }
-
- @Test
- @Ignore // TODO RestconfDocumentedExceptionMapper needs be fixed before
- public void stringToNumberConversionError() {
- final Response response = target("/config/number:cont").request(MediaType.APPLICATION_XML).put(
- Entity.entity("<cont xmlns=\"number\"><lf>3f</lf></cont>", MediaType.APPLICATION_XML));
- final String exceptionMessage = response.readEntity(String.class);
- assertTrue(exceptionMessage.contains("invalid-value"));
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.Encoded;
-import javax.ws.rs.GET;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.BeforeClass;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeJsonBodyWriter;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeXmlBodyWriter;
-import org.opendaylight.netconf.sal.rest.impl.RestconfDocumentedExceptionMapper;
-import org.opendaylight.netconf.sal.rest.impl.WriterParameters;
-import org.opendaylight.netconf.sal.rest.impl.XmlNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.netconf.sal.restconf.impl.QueryParametersParser;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.SystemLeafSetNode;
-import org.opendaylight.yangtools.yang.data.api.schema.SystemMapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.CollectionNodeBuilder;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.ListNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class CutDataToCorrectDepthTest extends JerseyTest {
-
- private static final Logger LOG = LoggerFactory.getLogger(JerseyTest.class);
-
- private static NormalizedNode depth1Cont;
- private static NormalizedNode depth2Cont1;
- private NormalizedNode globalPayload;
- private static EffectiveModelContext schemaContextModules;
-
- private final ControllerContext controllerContext =
- TestRestconfUtils.newControllerContext(schemaContextModules, null);
-
- @Path("/")
- public class RestImpl {
-
- @GET
- @Path("/config/{identifier:.+}")
- @Produces({ "application/json", "application/xml" })
- public NormalizedNodeContext getData(@Encoded @PathParam("identifier") final String identifier,
- @Context final UriInfo uriInfo) {
-
- final InstanceIdentifierContext iiWithData = controllerContext.toInstanceIdentifier(identifier);
-
- NormalizedNode data = null;
- if (identifier.equals("nested-module:depth1-cont/depth2-cont1")) {
- data = depth2Cont1;
- } else if (identifier.equals("nested-module:depth1-cont")) {
- data = depth1Cont;
- }
-
- final WriterParameters writerParameters = QueryParametersParser.parseWriterParameters(uriInfo);
- return new NormalizedNodeContext(iiWithData, data, writerParameters);
- }
-
- @GET
- @Path("/operational/{identifier:.+}")
- @Produces({ "application/json", "application/xml" })
- public NormalizedNodeContext getDataOperational(@Encoded @PathParam("identifier") final String identifier,
- @Context final UriInfo uriInfo) {
- return getData(identifier, uriInfo);
- }
-
- @PUT
- @Path("/config/{identifier:.+}")
- @Consumes({ "application/json", "application/xml" })
- public void normalizedData(@Encoded @PathParam("identifier") final String identifier,
- final NormalizedNodeContext payload) throws InterruptedException {
- LOG.info("Payload: {}.", payload);
- LOG.info("Instance identifier of payload: {}.",
- payload.getInstanceIdentifierContext().getInstanceIdentifier());
- LOG.info("Data of payload: {}.", payload.getData());
- globalPayload = payload.getData();
- }
-
- @PUT
- @Path("/operational/{identifier:.+}")
- @Consumes({ "application/json", "application/xml" })
- public void normalizedDataOperational(@Encoded @PathParam("identifier") final String identifier,
- final NormalizedNodeContext payload) throws InterruptedException {
- normalizedData(identifier, payload);
- }
- }
-
- @BeforeClass
- public static void initialize() throws FileNotFoundException, ReactorException {
- schemaContextModules = TestUtils.loadSchemaContext("/modules");
- final Module module = TestUtils.findModule(schemaContextModules.getModules(), "nested-module");
- assertNotNull(module);
-
- final UnkeyedListNode listAsUnkeyedList = unkeyedList(
- "depth2-cont1",
- unkeyedEntry("depth2-cont1",
- container("depth3-cont1",
- container("depth4-cont1", leaf("depth5-leaf1", "depth5-leaf1-value")),
- leaf("depth4-leaf1", "depth4-leaf1-value")), leaf("depth3-leaf1", "depth3-leaf1-value")));
-
- final MapNode listAsMap = mapNode(
- "depth2-list2",
- mapEntryNode("depth2-list2", 2, leaf("depth3-lf1-key", "depth3-lf1-key-value"),
- leaf("depth3-lf2-key", "depth3-lf2-key-value"), leaf("depth3-lf3", "depth3-lf3-value")));
-
- depth1Cont = container(
- "depth1-cont",
- listAsUnkeyedList,
- listAsMap,
- leafList("depth2-lfLst1", "depth2-lflst1-value1", "depth2-lflst1-value2", "depth2-lflst1-value3"),
- container(
- "depth2-cont2",
- container("depth3-cont2",
- container("depth4-cont2", leaf("depth5-leaf2", "depth5-leaf2-value")),
- leaf("depth4-leaf2", "depth4-leaf2-value")), leaf("depth3-leaf2", "depth3-leaf2-value")),
- leaf("depth2-leaf1", "depth2-leaf1-value"));
-
- depth2Cont1 = listAsUnkeyedList;
- }
-
- // TODO: These tests should be fixed/rewriten because they fail randomly due to data not being de-serialized
- // properly in readers
- //@Test
- public void getDataWithUriDepthParameterTest() throws WebApplicationException, IOException {
- getDataWithUriDepthParameter("application/json");
- getDataWithUriDepthParameter("application/xml");
- }
-
- public void getDataWithUriDepthParameter(final String mediaType) throws WebApplicationException, IOException {
- Response response;
-
- // Test config with depth 1
- response = target("/config/nested-module:depth1-cont").queryParam("depth", "1").request(mediaType)
- .get();
- txtDataToNormalizedNode(response, mediaType, "/config/nested-module:depth1-cont");
- verifyResponse(nodeDataDepth1());
-
- // Test config with depth 2
- response = target("/config/nested-module:depth1-cont").queryParam("depth", "2").request(mediaType)
- .get();
- txtDataToNormalizedNode(response, mediaType, "/config/nested-module:depth1-cont");
- verifyResponse(nodeDataDepth2());
-
- // Test config with depth 3
- response = target("/config/nested-module:depth1-cont").queryParam("depth", "3").request(mediaType)
- .get();
- txtDataToNormalizedNode(response, mediaType, "/config/nested-module:depth1-cont");
- verifyResponse(nodeDataDepth3());
-
- // Test config with depth 4
- response = target("/config/nested-module:depth1-cont").queryParam("depth", "4").request(mediaType)
- .get();
- txtDataToNormalizedNode(response, mediaType, "/config/nested-module:depth1-cont");
- verifyResponse(nodeDataDepth4());
-
- // Test config with depth 5
- response = target("/config/nested-module:depth1-cont").queryParam("depth", "5").request(mediaType)
- .get();
- txtDataToNormalizedNode(response, mediaType, "/config/nested-module:depth1-cont");
- verifyResponse(nodeDataDepth5());
-
- // Test config with depth unbounded
-
- response = target("/config/nested-module:depth1-cont").queryParam("depth", "unbounded")
- .request(mediaType).get();
- txtDataToNormalizedNode(response, mediaType, "/config/nested-module:depth1-cont");
- verifyResponse(nodeDataDepth5());
- }
-
- private void txtDataToNormalizedNode(final Response response, final String mediaType, final String uri) {
- final String responseStr = response.readEntity(String.class);
- LOG.info("Response entity message: {}.", responseStr);
- target(uri).request(mediaType).put(Entity.entity(responseStr, mediaType));
- }
-
- private void verifyResponse(final NormalizedNode nodeData) throws WebApplicationException, IOException {
- assertNotNull(globalPayload);
- assertEquals(globalPayload, nodeData);
- globalPayload = null;
- }
-
- @Override
- protected Application configure() {
- ResourceConfig resourceConfig = new ResourceConfig();
- resourceConfig = resourceConfig.registerInstances(new RestImpl());
- resourceConfig.registerClasses(XmlNormalizedNodeBodyReader.class, NormalizedNodeXmlBodyWriter.class,
- JsonNormalizedNodeBodyReader.class, NormalizedNodeJsonBodyWriter.class,
- RestconfDocumentedExceptionMapper.class);
- return resourceConfig;
- }
-
- private static LeafNode<?> leaf(final String localName, final Object value) {
- return Builders.leafBuilder().withNodeIdentifier(toIdentifier(localName)).withValue(value).build();
- }
-
- private static ContainerNode container(final String localName, final DataContainerChild... children) {
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> containerBuilder =
- Builders.containerBuilder();
- for (final DataContainerChild child : children) {
- containerBuilder.withChild(child);
- }
- containerBuilder.withNodeIdentifier(toIdentifier(localName));
- return containerBuilder.build();
- }
-
- private static UnkeyedListNode unkeyedList(
- final String localName,
- final UnkeyedListEntryNode... entryNodes) {
- final CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode> builder = Builders.unkeyedListBuilder();
- final NodeIdentifier identifier = toIdentifier(localName);
- builder.withNodeIdentifier(identifier);
- for (final UnkeyedListEntryNode unkeyedListEntryNode : entryNodes) {
- builder.withChild(unkeyedListEntryNode);
- }
- return builder.build();
- }
-
- private static UnkeyedListEntryNode unkeyedEntry(final String localName, final DataContainerChild... children) {
- final DataContainerNodeBuilder<NodeIdentifier, UnkeyedListEntryNode> builder =
- Builders.unkeyedListEntryBuilder();
- builder.withNodeIdentifier(toIdentifier(localName));
- for (final DataContainerChild child : children) {
- builder.withChild(child);
- }
- return builder.build();
- }
-
- private static MapNode mapNode(final String localName, final MapEntryNode... entryNodes) {
- final CollectionNodeBuilder<MapEntryNode, SystemMapNode> builder = Builders.mapBuilder();
- builder.withNodeIdentifier(toIdentifier(localName));
- for (final MapEntryNode mapEntryNode : entryNodes) {
- builder.withChild(mapEntryNode);
- }
- return builder.build();
- }
-
- private static MapEntryNode mapEntryNode(final String localName, final int keysNumber,
- final DataContainerChild... children) {
- final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> builder =
- Builders.mapEntryBuilder();
- final Map<QName, Object> keys = new HashMap<>();
- for (int i = 0; i < keysNumber; i++) {
- keys.put(children[i].getIdentifier().getNodeType(), children[i].body());
- }
- builder.withNodeIdentifier(toIdentifier(localName, keys));
-
- for (final DataContainerChild child : children) {
- builder.withChild(child);
- }
- return builder.build();
- }
-
- private static LeafSetNode<?> leafList(final String localName, final String... children) {
- final ListNodeBuilder<Object, SystemLeafSetNode<Object>> builder = Builders.leafSetBuilder();
- builder.withNodeIdentifier(toIdentifier(localName));
- for (final String child : children) {
- builder.withChild(Builders.leafSetEntryBuilder().withNodeIdentifier(toIdentifier(localName, child))
- .withValue(child).build());
- }
- return builder.build();
- }
-
- private static NodeIdentifier toIdentifier(final String localName) {
- return new NodeIdentifier(QName.create("urn:nested:module", "2014-06-03", localName));
- }
-
- private static NodeIdentifierWithPredicates toIdentifier(final String localName, final Map<QName, Object> keys) {
- return NodeIdentifierWithPredicates.of(QName.create("urn:nested:module", "2014-06-03", localName), keys);
- }
-
- private static NodeWithValue<?> toIdentifier(final String localName, final Object value) {
- return new NodeWithValue<>(QName.create("urn:nested:module", "2014-06-03", localName), value);
- }
-
- private static UnkeyedListEntryNode nodeDataDepth3Operational() {
- return unkeyedEntry("depth2-cont1",
- container("depth3-cont1", container("depth4-cont1"), leaf("depth4-leaf1", "depth4-leaf1-value")),
- leaf("depth3-leaf1", "depth3-leaf1-value"));
- }
-
- private static ContainerNode nodeDataDepth5() {
- return container(
- "depth1-cont",
- unkeyedList(
- "depth2-cont1",
- unkeyedEntry("depth2-cont1",
- container("depth3-cont1",
- container("depth4-cont1", leaf("depth5-leaf1", "depth5-leaf1-value")),
- leaf("depth4-leaf1", "depth4-leaf1-value")),
- leaf("depth3-leaf1", "depth3-leaf1-value"))),
- mapNode("depth2-list2",
- mapEntryNode("depth2-list2", 2, leaf("depth3-lf1-key", "depth3-lf1-key-value"),
- leaf("depth3-lf2-key", "depth3-lf2-key-value"), leaf("depth3-lf3", "depth3-lf3-value"))),
- leafList("depth2-lfLst1", "depth2-lflst1-value1", "depth2-lflst1-value2", "depth2-lflst1-value3"),
- container(
- "depth2-cont2",
- container("depth3-cont2",
- container("depth4-cont2", leaf("depth5-leaf2", "depth5-leaf2-value")),
- leaf("depth4-leaf2", "depth4-leaf2-value")), leaf("depth3-leaf2", "depth3-leaf2-value")),
- leaf("depth2-leaf1", "depth2-leaf1-value"));
- }
-
- private static ContainerNode nodeDataDepth4() {
- return container(
- "depth1-cont",
- unkeyedList("depth2-cont1", nodeDataDepth3Operational()),
- mapNode("depth2-list2",
- mapEntryNode("depth2-list2", 2, leaf("depth3-lf1-key", "depth3-lf1-key-value"),
- leaf("depth3-lf2-key", "depth3-lf2-key-value"), leaf("depth3-lf3", "depth3-lf3-value"))),
- leafList("depth2-lfLst1", "depth2-lflst1-value1", "depth2-lflst1-value2", "depth2-lflst1-value3"),
- container(
- "depth2-cont2",
- container("depth3-cont2", container("depth4-cont2"), leaf("depth4-leaf2", "depth4-leaf2-value")),
- leaf("depth3-leaf2", "depth3-leaf2-value")), leaf("depth2-leaf1", "depth2-leaf1-value"));
- }
-
- private static ContainerNode nodeDataDepth3() {
- return container(
- "depth1-cont",
- unkeyedList("depth2-cont1",
- unkeyedEntry("depth2-cont1", container("depth3-cont1"), leaf("depth3-leaf1", "depth3-leaf1-value"))),
- mapNode("depth2-list2",
- mapEntryNode("depth2-list2", 2, leaf("depth3-lf1-key", "depth3-lf1-key-value"),
- leaf("depth3-lf2-key", "depth3-lf2-key-value"), leaf("depth3-lf3", "depth3-lf3-value"))),
- leafList("depth2-lfLst1", "depth2-lflst1-value1", "depth2-lflst1-value2", "depth2-lflst1-value3"),
- container("depth2-cont2", container("depth3-cont2"), leaf("depth3-leaf2", "depth3-leaf2-value")),
- leaf("depth2-leaf1", "depth2-leaf1-value"));
- }
-
- private static ContainerNode nodeDataDepth2() {
- return container(
- "depth1-cont",
- unkeyedList("depth2-cont1", unkeyedEntry("depth2-cont1")),
- mapNode("depth2-list2",
- mapEntryNode("depth2-list2", 2, leaf("depth3-lf1-key", "depth3-lf1-key-value"),
- leaf("depth3-lf2-key", "depth3-lf2-key-value"))), container("depth2-cont2"),
-// leafList("depth2-lfLst1"),
- leaf("depth2-leaf1", "depth2-leaf1-value"));
- }
-
- private static ContainerNode nodeDataDepth1() {
- return container("depth1-cont");
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-
-public class DummyFuture<T> implements Future<RpcResult<T>> {
-
- private final boolean cancel;
- private final boolean isCancelled;
- private final boolean isDone;
- private final RpcResult<T> result;
-
- public DummyFuture() {
- cancel = false;
- isCancelled = false;
- isDone = false;
- result = null;
- }
-
- private DummyFuture(final Builder<T> builder) {
- cancel = builder.cancel;
- isCancelled = builder.isCancelled;
- isDone = builder.isDone;
- result = builder.result;
- }
-
- @Override
- public boolean cancel(final boolean mayInterruptIfRunning) {
- return cancel;
- }
-
- @Override
- public boolean isCancelled() {
- return isCancelled;
- }
-
- @Override
- public boolean isDone() {
- return isDone;
- }
-
- @Override
- public RpcResult<T> get() throws InterruptedException, ExecutionException {
- return result;
- }
-
- @Override
- public RpcResult<T> get(final long timeout, final TimeUnit unit) throws InterruptedException, ExecutionException,
- TimeoutException {
- return result;
- }
-
- public static class Builder<T> {
-
- private boolean cancel;
- private boolean isCancelled;
- private boolean isDone;
- private RpcResult<T> result;
-
- public Builder<T> cancel(final boolean newCancel) {
- this.cancel = newCancel;
- return this;
- }
-
- public Builder<T> isCancelled(final boolean cancelled) {
- this.isCancelled = cancelled;
- return this;
- }
-
- public Builder<T> isDone(final boolean done) {
- this.isDone = done;
- return this;
- }
-
- public Builder<T> rpcResult(final RpcResult<T> newResult) {
- this.result = newResult;
- return this;
- }
-
- public Future<RpcResult<T>> build() {
- return new DummyFuture<>(this);
- }
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-import java.util.List;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-
-public class DummyRpcResult<T> implements RpcResult<T> {
-
- private final boolean isSuccessful;
- private final T result;
- private final List<RpcError> errors;
-
- public DummyRpcResult() {
- isSuccessful = false;
- result = null;
- errors = null;
- }
-
- private DummyRpcResult(final Builder<T> builder) {
- isSuccessful = builder.isSuccessful;
- result = builder.result;
- errors = builder.errors;
- }
-
- @Override
- public boolean isSuccessful() {
- return isSuccessful;
- }
-
- @Override
- public T getResult() {
- return result;
- }
-
- @Override
- public List<RpcError> getErrors() {
- return errors;
- }
-
- public static class Builder<T> {
- private boolean isSuccessful;
- private T result;
- private List<RpcError> errors;
-
- public Builder<T> isSuccessful(final boolean successful) {
- this.isSuccessful = successful;
- return this;
- }
-
- public Builder<T> result(final T newResult) {
- this.result = newResult;
- return this;
- }
-
- public Builder<T> errors(final List<RpcError> newErrors) {
- this.errors = newErrors;
- return this;
- }
-
- public RpcResult<T> build() {
- return new DummyRpcResult<>(this);
- }
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-import java.util.List;
-import java.util.Optional;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.Status;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
-
-public class DummyType implements TypeDefinition<DummyType> {
- QName dummyQName = TestUtils.buildQName("dummy type", "simple:uri", "2012-12-17");
-
- @Override
- public QName getQName() {
- return dummyQName;
- }
-
- @Override
- public Optional<String> getDescription() {
- return Optional.empty();
- }
-
- @Override
- public Optional<String> getReference() {
- return Optional.empty();
- }
-
- @Override
- public Status getStatus() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public List<UnknownSchemaNode> getUnknownSchemaNodes() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public DummyType getBaseType() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public Optional<String> getUnits() {
- return Optional.empty();
- }
-
- @Override
- public Optional<? extends Object> getDefaultValue() {
- return Optional.empty();
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.nio.charset.StandardCharsets;
-import java.time.Instant;
-import java.util.Collection;
-import java.util.Optional;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.netconf.sal.streams.listeners.ListenerAdapter;
-import org.opendaylight.netconf.sal.streams.listeners.Notificator;
-import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping.NotificationOutputType;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-
-public class ExpressionParserTest {
-
- private Collection<File> xmls;
-
- @Before
- public void setup() throws Exception {
- this.xmls = TestRestconfUtils.loadFiles("/notifications/xml/output/");
- }
-
- @Test
- public void trueDownFilterTest() throws Exception {
- final boolean parser =
- parser("notification/data-changed-notification/data-change-event/data/toasterStatus='down'",
- "data_change_notification_toaster_status_DOWN.xml");
- Assert.assertTrue(parser);
- }
-
- @Test
- public void falseDownFilterTest() throws Exception {
- final boolean parser =
- parser("notification/data-changed-notification/data-change-event/data/toasterStatus='up'",
- "data_change_notification_toaster_status_DOWN.xml");
- Assert.assertFalse(parser);
- }
-
- @Test
- public void trueNumberEqualsFilterTest() throws Exception {
- final boolean parser = parser(
- "notification/data-changed-notification/data-change-event/data/toasterStatus=1",
- "data_change_notification_toaster_status_NUMBER.xml");
- Assert.assertTrue(parser);
- }
-
- @Test
- public void falseNumberEqualsFilterTest() throws Exception {
- final boolean parser = parser("notification/data-changed-notification/data-change-event/data/toasterStatus=0",
- "data_change_notification_toaster_status_NUMBER.xml");
- Assert.assertFalse(parser);
- }
-
- @Test
- public void trueNumberLessFilterTest() throws Exception {
- final boolean parser = parser("notification/data-changed-notification/data-change-event/data/toasterStatus<2",
- "data_change_notification_toaster_status_NUMBER.xml");
- Assert.assertTrue(parser);
- }
-
- @Test
- public void falseNumberLessFilterTest() throws Exception {
- final boolean parser = parser("notification/data-changed-notification/data-change-event/data/toasterStatus<0",
- "data_change_notification_toaster_status_NUMBER.xml");
- Assert.assertFalse(parser);
- }
-
- @Test
- public void trueNumberLessEqualsFilterTest() throws Exception {
- final boolean parser = parser("notification/data-changed-notification/data-change-event/data/toasterStatus<=2",
- "data_change_notification_toaster_status_NUMBER.xml");
- Assert.assertTrue(parser);
- }
-
- @Test
- public void falseNumberLessEqualsFilterTest() throws Exception {
- final boolean parser = parser("notification/data-changed-notification/data-change-event/data/toasterStatus<=-1",
- "data_change_notification_toaster_status_NUMBER.xml");
- Assert.assertFalse(parser);
- }
-
- @Test
- public void trueNumberGreaterFilterTest() throws Exception {
- final boolean parser = parser("notification/data-changed-notification/data-change-event/data/toasterStatus>0",
- "data_change_notification_toaster_status_NUMBER.xml");
- Assert.assertTrue(parser);
- }
-
- @Test
- public void falseNumberGreaterFilterTest() throws Exception {
- final boolean parser = parser("notification/data-changed-notification/data-change-event/data/toasterStatus>5",
- "data_change_notification_toaster_status_NUMBER.xml");
- Assert.assertFalse(parser);
- }
-
- @Test
- public void trueNumberGreaterEqualsFilterTest() throws Exception {
- final boolean parser = parser("notification/data-changed-notification/data-change-event/data/toasterStatus>=0",
- "data_change_notification_toaster_status_NUMBER.xml");
- Assert.assertTrue(parser);
- }
-
- @Test
- public void falseNumberGreaterEqualsFilterTest() throws Exception {
- final boolean parser = parser("notification/data-changed-notification/data-change-event/data/toasterStatus>=5",
- "data_change_notification_toaster_status_NUMBER.xml");
- Assert.assertFalse(parser);
- }
-
- private boolean parser(final String filter, final String fileName) throws Exception {
- File xml = null;
- for (final File file : this.xmls) {
- if (file.getName().equals(fileName)) {
- xml = file;
- }
- }
- final YangInstanceIdentifier path = Mockito.mock(YangInstanceIdentifier.class);
- final PathArgument pathValue = NodeIdentifier.create(QName.create("module", "2016-12-14", "localName"));
- Mockito.when(path.getLastPathArgument()).thenReturn(pathValue);
- final ListenerAdapter listener = Notificator.createListener(path, "streamName", NotificationOutputType.JSON,
- null);
- listener.setQueryParams(Instant.now(), Optional.empty(), Optional.ofNullable(filter), false, false);
-
- // FIXME: do not use reflection here
- final Class<?> superclass = listener.getClass().getSuperclass().getSuperclass();
- Method method = null;
- for (final Method met : superclass.getDeclaredMethods()) {
- if (met.getName().equals("parseFilterParam")) {
- method = met;
- }
- }
- if (method == null) {
- throw new Exception("Methode parseFilterParam doesn't exist in " + superclass.getName());
- }
- method.setAccessible(true);
- return (boolean) method.invoke(listener, readFile(xml));
- }
-
- private static String readFile(final File xml) throws IOException {
- try (BufferedReader br = new BufferedReader(new FileReader(xml, StandardCharsets.UTF_8))) {
- final StringBuilder sb = new StringBuilder();
- String line = br.readLine();
-
- while (line != null) {
- sb.append(line);
- sb.append("\n");
- line = br.readLine();
- }
- return sb.toString();
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013, 2015 Brocade Communication Systems, Inc., 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.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doCallRealMethod;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFailedFluentFuture;
-import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFluentFuture;
-
-import java.io.FileNotFoundException;
-import java.util.Collection;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MultivaluedHashMap;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-import org.junit.BeforeClass;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException;
-import org.opendaylight.mdsal.dom.api.DOMRpcResult;
-import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.restconf.impl.BrokerFacade;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.netconf.sal.restconf.impl.RestconfImpl;
-import org.opendaylight.restconf.common.ErrorTags;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.errors.RestconfError;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.common.ErrorType;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-import org.opendaylight.yangtools.yang.common.XMLNamespace;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.NormalizedNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.SchemaAwareBuilders;
-import org.opendaylight.yangtools.yang.model.api.ContainerLike;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.InputSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
-
-public class InvokeRpcMethodTest {
-
- private static UriInfo uriInfo;
- private static EffectiveModelContext schemaContext;
-
- private final RestconfImpl restconfImpl;
- private final ControllerContext controllerContext;
- private final BrokerFacade brokerFacade = mock(BrokerFacade.class);
-
- public InvokeRpcMethodTest() {
- controllerContext = TestRestconfUtils.newControllerContext(schemaContext);
- restconfImpl = RestconfImpl.newInstance(brokerFacade, controllerContext);
- }
-
- @BeforeClass
- public static void init() throws FileNotFoundException, ReactorException {
- schemaContext = TestUtils.loadSchemaContext("/full-versions/yangs", "/invoke-rpc");
- final Collection<? extends Module> allModules = schemaContext.getModules();
- assertNotNull(allModules);
- final Module module = TestUtils.resolveModule("invoke-rpc-module", allModules);
- assertNotNull(module);
-
- uriInfo = mock(UriInfo.class);
- final MultivaluedMap<String, String> map = new MultivaluedHashMap<>();
- map.put("prettyPrint", List.of("true"));
- doReturn(map).when(uriInfo).getQueryParameters(any(Boolean.class));
- }
-
- /**
- * Test method invokeRpc in RestconfImpl class tests if composite node as input parameter of method invokeRpc
- * (second argument) is wrapped to parent composite node which has QName equals to QName of rpc (resolved from
- * string - first argument).
- */
- @Test
- public void invokeRpcMethodTest() {
- controllerContext.findModuleNameByNamespace(XMLNamespace.of("invoke:rpc:module"));
-
- final NormalizedNodeContext payload = prepareDomPayload();
-
- final NormalizedNodeContext rpcResponse =
- restconfImpl.invokeRpc("invoke-rpc-module:rpc-test", payload, uriInfo);
- assertNotNull(rpcResponse);
- assertNull(rpcResponse.getData());
-
- }
-
- private NormalizedNodeContext prepareDomPayload() {
- final EffectiveModelContext schema = controllerContext.getGlobalSchema();
- final Module rpcModule = schema.findModules("invoke-rpc-module").iterator().next();
- assertNotNull(rpcModule);
- final QName rpcQName = QName.create(rpcModule.getQNameModule(), "rpc-test");
- RpcDefinition rpcSchemaNode = null;
- for (final RpcDefinition rpc : rpcModule.getRpcs()) {
- if (rpcQName.isEqualWithoutRevision(rpc.getQName())) {
- rpcSchemaNode = rpc;
- break;
- }
- }
- assertNotNull(rpcSchemaNode);
- final InputSchemaNode rpcInputSchemaNode = rpcSchemaNode.getInput();
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> container =
- SchemaAwareBuilders.containerBuilder(rpcInputSchemaNode);
-
- final QName contQName = QName.create(rpcModule.getQNameModule(), "cont");
- final DataSchemaNode contSchemaNode = rpcInputSchemaNode.getDataChildByName(contQName);
- assertTrue(contSchemaNode instanceof ContainerSchemaNode);
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> contNode =
- SchemaAwareBuilders.containerBuilder((ContainerSchemaNode) contSchemaNode);
-
- final QName lfQName = QName.create(rpcModule.getQNameModule(), "lf");
- final DataSchemaNode lfSchemaNode = ((ContainerSchemaNode) contSchemaNode).getDataChildByName(lfQName);
- assertTrue(lfSchemaNode instanceof LeafSchemaNode);
- final LeafNode<Object> lfNode =
- SchemaAwareBuilders.leafBuilder((LeafSchemaNode) lfSchemaNode).withValue("any value").build();
- contNode.withChild(lfNode);
- container.withChild(contNode.build());
-
- return new NormalizedNodeContext(InstanceIdentifierContext.ofRpcInput(schema, rpcSchemaNode, null),
- container.build());
- }
-
- @Test
- public void testInvokeRpcWithNoPayloadRpc_FailNoErrors() {
- final QName qname = QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)cancel-toast");
-
- doReturn(immediateFailedFluentFuture(new DOMRpcImplementationNotAvailableException("testExeption")))
- .when(brokerFacade).invokeRpc(eq(qname), any());
-
- final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
- () -> restconfImpl.invokeRpc("toaster:cancel-toast", null, uriInfo));
- verifyRestconfDocumentedException(ex, 0, ErrorType.APPLICATION, ErrorTag.OPERATION_NOT_SUPPORTED,
- Optional.empty(), Optional.empty());
- }
-
- void verifyRestconfDocumentedException(final RestconfDocumentedException restDocumentedException, final int index,
- final ErrorType expErrorType, final ErrorTag expErrorTag, final Optional<String> expErrorMsg,
- final Optional<String> expAppTag) {
-
- final List<RestconfError> errors = restDocumentedException.getErrors();
- assertTrue("RestconfError not found at index " + index, errors.size() > index);
-
- RestconfError actual = errors.get(index);
-
- assertEquals("getErrorType", expErrorType, actual.getErrorType());
- assertEquals("getErrorTag", expErrorTag, actual.getErrorTag());
- assertNotNull("getErrorMessage is null", actual.getErrorMessage());
-
- if (expErrorMsg.isPresent()) {
- assertEquals("getErrorMessage", expErrorMsg.get(), actual.getErrorMessage());
- }
-
- if (expAppTag.isPresent()) {
- assertEquals("getErrorAppTag", expAppTag.get(), actual.getErrorAppTag());
- }
- }
-
- @Test
- public void testInvokeRpcWithNoPayloadRpc_FailWithRpcError() {
- final List<RpcError> rpcErrors = List.of(
- RpcResultBuilder.newError(ErrorType.TRANSPORT, new ErrorTag("bogusTag"), "foo"),
- RpcResultBuilder.newWarning(ErrorType.RPC, ErrorTag.IN_USE, "bar", "app-tag", null, null));
-
- final DOMRpcResult result = new DefaultDOMRpcResult(rpcErrors);
- final QName path = QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)cancel-toast");
- doReturn(immediateFluentFuture(result)).when(brokerFacade).invokeRpc(eq(path), any());
-
- final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
- () -> restconfImpl.invokeRpc("toaster:cancel-toast", null, uriInfo));
-
- // We are performing pass-through here of error-tag, hence the tag remains as specified, but we want to make
- // sure the HTTP status remains the same as
- final ErrorTag bogus = new ErrorTag("bogusTag");
- verifyRestconfDocumentedException(ex, 0, ErrorType.TRANSPORT, bogus, Optional.of("foo"), Optional.empty());
- assertEquals(ErrorTags.statusOf(ErrorTag.OPERATION_FAILED), ErrorTags.statusOf(bogus));
-
- verifyRestconfDocumentedException(ex, 1, ErrorType.RPC, ErrorTag.IN_USE, Optional.of("bar"),
- Optional.of("app-tag"));
- }
-
- @Test
- public void testInvokeRpcWithNoPayload_Success() {
- final NormalizedNode resultObj = null;
- final DOMRpcResult expResult = new DefaultDOMRpcResult(resultObj);
-
- final QName qname = QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)cancel-toast");
-
- doReturn(immediateFluentFuture(expResult)).when(brokerFacade).invokeRpc(eq(qname), any());
-
- final NormalizedNodeContext output = restconfImpl.invokeRpc("toaster:cancel-toast", null, uriInfo);
- assertNotNull(output);
- assertEquals(null, output.getData());
- // additional validation in the fact that the restconfImpl does not
- // throw an exception.
- }
-
- @Test
- public void testInvokeRpcWithEmptyOutput() {
- final ContainerNode resultObj = mock(ContainerNode.class);
- doReturn(Set.of()).when(resultObj).body();
- doCallRealMethod().when(resultObj).isEmpty();
- final DOMRpcResult expResult = new DefaultDOMRpcResult(resultObj);
-
- final QName qname = QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)cancel-toast");
- doReturn(immediateFluentFuture(expResult)).when(brokerFacade).invokeRpc(eq(qname), any());
-
- WebApplicationException exceptionToBeThrown = assertThrows(WebApplicationException.class,
- () -> restconfImpl.invokeRpc("toaster:cancel-toast", null, uriInfo));
- assertEquals(Response.Status.NO_CONTENT.getStatusCode(), exceptionToBeThrown.getResponse().getStatus());
- }
-
- @Test
- public void testInvokeRpcMethodWithBadMethodName() {
- final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
- () -> restconfImpl.invokeRpc("toaster:bad-method", null, uriInfo));
- verifyRestconfDocumentedException(ex, 0, ErrorType.RPC, ErrorTag.UNKNOWN_ELEMENT,
- Optional.empty(), Optional.empty());
- }
-
- @Test
- @Ignore
- public void testInvokeRpcMethodWithInput() {
- final DOMRpcResult expResult = mock(DOMRpcResult.class);
- final QName path = QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)make-toast");
-
- final Module rpcModule = schemaContext.findModules("toaster").iterator().next();
- assertNotNull(rpcModule);
- final QName rpcQName = QName.create(rpcModule.getQNameModule(), "make-toast");
-
- RpcDefinition rpcDef = null;
- for (final RpcDefinition rpc : rpcModule.getRpcs()) {
- if (rpcQName.isEqualWithoutRevision(rpc.getQName())) {
- rpcDef = rpc;
- break;
- }
- }
-
- assertNotNull(rpcDef);
-
- final NormalizedNodeContext payload = new NormalizedNodeContext(
- InstanceIdentifierContext.ofLocalRpcInput(schemaContext, rpcDef),
- SchemaAwareBuilders.containerBuilder(rpcDef.getInput()).build());
-
- doReturn(immediateFluentFuture(expResult)).when(brokerFacade).invokeRpc(eq(path), any(NormalizedNode.class));
-
- final NormalizedNodeContext output = restconfImpl.invokeRpc("toaster:make-toast", payload, uriInfo);
- assertNotNull(output);
- assertEquals(null, output.getData());
- // additional validation in the fact that the restconfImpl does not
- // throw an exception.
- }
-
- @Test
- public void testThrowExceptionWhenSlashInModuleName() {
- final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
- () -> restconfImpl.invokeRpc("toaster/slash", null, uriInfo));
- verifyRestconfDocumentedException(ex, 0, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE,
- Optional.empty(), Optional.empty());
- }
-
- @Test
- public void testInvokeRpcWithNoPayloadWithOutput_Success() {
- final SchemaContext schema = controllerContext.getGlobalSchema();
- final Module rpcModule = schema.findModules("toaster").iterator().next();
- assertNotNull(rpcModule);
- final QName rpcQName = QName.create(rpcModule.getQNameModule(), "testOutput");
- final QName rpcOutputQName = QName.create(rpcModule.getQNameModule(),"output");
-
- RpcDefinition rpcDef = null;
- ContainerLike rpcOutputSchemaNode = null;
- for (final RpcDefinition rpc : rpcModule.getRpcs()) {
- if (rpcQName.isEqualWithoutRevision(rpc.getQName())) {
- rpcOutputSchemaNode = rpc.getOutput();
- rpcDef = rpc;
- break;
- }
- }
- assertNotNull(rpcDef);
- assertNotNull(rpcOutputSchemaNode);
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> containerBuilder =
- SchemaAwareBuilders.containerBuilder(rpcOutputSchemaNode);
- final DataSchemaNode leafSchema = rpcOutputSchemaNode
- .getDataChildByName(QName.create(rpcModule.getQNameModule(), "textOut"));
- assertTrue(leafSchema instanceof LeafSchemaNode);
- final NormalizedNodeBuilder<NodeIdentifier, Object, LeafNode<Object>> leafBuilder =
- SchemaAwareBuilders.leafBuilder((LeafSchemaNode) leafSchema);
- leafBuilder.withValue("brm");
- containerBuilder.withChild(leafBuilder.build());
- final ContainerNode container = containerBuilder.build();
-
- final DOMRpcResult result = new DefaultDOMRpcResult(container);
-
- doReturn(immediateFluentFuture(result)).when(brokerFacade).invokeRpc(eq(rpcDef.getQName()), any());
-
- final NormalizedNodeContext output = restconfImpl.invokeRpc("toaster:testOutput", null, uriInfo);
- assertNotNull(output);
- assertNotNull(output.getData());
- assertSame(container, output.getData());
- assertNotNull(output.getInstanceIdentifierContext());
- assertNotNull(output.getInstanceIdentifierContext().getSchemaContext());
- }
-
- /**
- * Tests calling of RestConfImpl method invokeRpc. In the method there is searched rpc in remote schema context.
- * This rpc is then executed.
- * I wasn't able to simulate calling of rpc on remote device therefore this testing method raise method when rpc is
- * invoked.
- */
- @Test
- public void testMountedRpcCallNoPayload_Success() throws Exception {
- // FIXME find how to use mockito for it
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Brocade Communications 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.controller.sal.restconf.impl.test;
-
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.ArgumentMatchers.same;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFailedFluentFuture;
-import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFluentFuture;
-
-import com.google.common.io.Resources;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-import java.util.Optional;
-import javax.ws.rs.core.Response.Status;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
-import org.opendaylight.mdsal.dom.api.DOMMountPoint;
-import org.opendaylight.mdsal.dom.api.DOMRpcException;
-import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException;
-import org.opendaylight.mdsal.dom.api.DOMRpcResult;
-import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
-import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
-import org.opendaylight.netconf.sal.restconf.impl.BrokerFacade;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.netconf.sal.restconf.impl.JSONRestconfServiceImpl;
-import org.opendaylight.netconf.sal.restconf.impl.PutResult;
-import org.opendaylight.netconf.sal.restconf.impl.RestconfImpl;
-import org.opendaylight.restconf.common.patch.PatchContext;
-import org.opendaylight.restconf.common.patch.PatchStatusContext;
-import org.opendaylight.restconf.common.patch.PatchStatusEntity;
-import org.opendaylight.yangtools.yang.common.OperationFailedException;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.Uint32;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
-
-/**
- * Unit tests for JSONRestconfServiceImpl.
- *
- * @author Thomas Pantelis
- */
-@Deprecated
-public class JSONRestconfServiceImplTest {
- static final String IETF_INTERFACES_NS = "urn:ietf:params:xml:ns:yang:ietf-interfaces";
- static final String IETF_INTERFACES_VERSION = "2013-07-04";
- static final QName INTERFACES_QNAME = QName.create(IETF_INTERFACES_NS, IETF_INTERFACES_VERSION, "interfaces");
- static final QName INTERFACE_QNAME = QName.create(IETF_INTERFACES_NS, IETF_INTERFACES_VERSION, "interface");
- static final QName NAME_QNAME = QName.create(IETF_INTERFACES_NS, IETF_INTERFACES_VERSION, "name");
- static final QName TYPE_QNAME = QName.create(IETF_INTERFACES_NS, IETF_INTERFACES_VERSION, "type");
- static final QName ENABLED_QNAME = QName.create(IETF_INTERFACES_NS, IETF_INTERFACES_VERSION, "enabled");
- static final QName DESC_QNAME = QName.create(IETF_INTERFACES_NS, IETF_INTERFACES_VERSION, "description");
-
- static final String TEST_MODULE_NS = "test:module";
- static final String TEST_MODULE_VERSION = "2014-01-09";
- static final QName TEST_CONT_QNAME = QName.create(TEST_MODULE_NS, TEST_MODULE_VERSION, "cont");
- static final QName TEST_CONT1_QNAME = QName.create(TEST_MODULE_NS, TEST_MODULE_VERSION, "cont1");
- static final QName TEST_LF11_QNAME = QName.create(TEST_MODULE_NS, TEST_MODULE_VERSION, "lf11");
- static final QName TEST_LF12_QNAME = QName.create(TEST_MODULE_NS, TEST_MODULE_VERSION, "lf12");
-
- static final String TOASTER_MODULE_NS = "http://netconfcentral.org/ns/toaster";
- static final String TOASTER_MODULE_VERSION = "2009-11-20";
- static final QName TOASTER_DONENESS_QNAME =
- QName.create(TOASTER_MODULE_NS, TOASTER_MODULE_VERSION, "toasterDoneness");
- static final QName TOASTER_TYPE_QNAME = QName.create(TOASTER_MODULE_NS, TOASTER_MODULE_VERSION, "toasterToastType");
- static final QName WHEAT_BREAD_QNAME = QName.create(TOASTER_MODULE_NS, TOASTER_MODULE_VERSION, "wheat-bread");
- static final QName MAKE_TOAST_QNAME = QName.create(TOASTER_MODULE_NS, TOASTER_MODULE_VERSION, "make-toast");
- static final QName CANCEL_TOAST_QNAME = QName.create(TOASTER_MODULE_NS, TOASTER_MODULE_VERSION, "cancel-toast");
- static final QName TEST_OUTPUT_QNAME = QName.create(TOASTER_MODULE_NS, TOASTER_MODULE_VERSION, "testOutput");
- static final QName TEXT_OUT_QNAME = QName.create(TOASTER_MODULE_NS, TOASTER_MODULE_VERSION, "textOut");
-
- private static EffectiveModelContext schemaContext;
-
- private final BrokerFacade brokerFacade = mock(BrokerFacade.class);
- private final DOMMountPoint mockMountPoint = mock(DOMMountPoint.class);
- private JSONRestconfServiceImpl service;
-
- @BeforeClass
- public static void init() throws IOException, ReactorException {
- schemaContext = TestUtils.loadSchemaContext("/full-versions/yangs");
- }
-
- @Before
- public void setup() throws FileNotFoundException {
- final EffectiveModelContext mountPointSchemaContext = TestUtils.loadSchemaContext("/full-versions/test-module");
- final ControllerContext controllerContext =
- TestRestconfUtils.newControllerContext(schemaContext, mockMountPoint);
- doReturn(java.util.Optional.of(FixedDOMSchemaService.of(() -> mountPointSchemaContext))).when(mockMountPoint)
- .getService(eq(DOMSchemaService.class));
-
- service = new JSONRestconfServiceImpl(controllerContext,
- RestconfImpl.newInstance(brokerFacade, controllerContext));
- }
-
- private static String loadData(final String path) throws IOException {
- return Resources.asCharSource(JSONRestconfServiceImplTest.class.getResource(path),
- StandardCharsets.UTF_8).read();
- }
-
- @Test
- public void testPut() throws Exception {
- final PutResult result = mock(PutResult.class);
- when(brokerFacade.commitConfigurationDataPut(any(EffectiveModelContext.class),
- any(YangInstanceIdentifier.class), any(NormalizedNode.class), isNull(), isNull()))
- .thenReturn(result);
- doReturn(CommitInfo.emptyFluentFuture()).when(result).getFutureOfPutData();
- when(result.getStatus()).thenReturn(Status.OK);
- final String uriPath = "ietf-interfaces:interfaces/interface/eth0";
- final String payload = loadData("/parts/ietf-interfaces_interfaces.json");
- service.put(uriPath, payload);
-
- final ArgumentCaptor<YangInstanceIdentifier> capturedPath =
- ArgumentCaptor.forClass(YangInstanceIdentifier.class);
- final ArgumentCaptor<NormalizedNode> capturedNode = ArgumentCaptor.forClass(NormalizedNode.class);
- verify(brokerFacade).commitConfigurationDataPut(any(EffectiveModelContext.class), capturedPath.capture(),
- capturedNode.capture(), isNull(), isNull());
-
- verifyPath(capturedPath.getValue(), INTERFACES_QNAME, INTERFACE_QNAME,
- new Object[]{INTERFACE_QNAME, NAME_QNAME, "eth0"});
-
- assertTrue("Expected MapEntryNode. Actual " + capturedNode.getValue().getClass(),
- capturedNode.getValue() instanceof MapEntryNode);
- final MapEntryNode actualNode = (MapEntryNode) capturedNode.getValue();
- assertEquals("MapEntryNode node type", INTERFACE_QNAME, actualNode.getIdentifier().getNodeType());
- verifyLeafNode(actualNode, NAME_QNAME, "eth0");
- verifyLeafNode(actualNode, TYPE_QNAME, "ethernetCsmacd");
- verifyLeafNode(actualNode, ENABLED_QNAME, Boolean.FALSE);
- verifyLeafNode(actualNode, DESC_QNAME, "some interface");
- }
-
- @Test
- public void testPutBehindMountPoint() throws Exception {
- final PutResult result = mock(PutResult.class);
- when(brokerFacade.commitMountPointDataPut(any(DOMMountPoint.class),
- any(YangInstanceIdentifier.class), any(NormalizedNode.class), isNull(), isNull()))
- .thenReturn(result);
- doReturn(CommitInfo.emptyFluentFuture()).when(result).getFutureOfPutData();
- when(result.getStatus()).thenReturn(Status.OK);
- final String uriPath = "ietf-interfaces:interfaces/yang-ext:mount/test-module:cont/cont1";
- final String payload = loadData("/full-versions/testCont1Data.json");
-
- service.put(uriPath, payload);
-
- final ArgumentCaptor<YangInstanceIdentifier> capturedPath =
- ArgumentCaptor.forClass(YangInstanceIdentifier.class);
- final ArgumentCaptor<NormalizedNode> capturedNode = ArgumentCaptor.forClass(NormalizedNode.class);
- verify(brokerFacade).commitMountPointDataPut(same(mockMountPoint), capturedPath.capture(),
- capturedNode.capture(), isNull(), isNull());
-
- verifyPath(capturedPath.getValue(), TEST_CONT_QNAME, TEST_CONT1_QNAME);
-
- assertTrue("Expected ContainerNode", capturedNode.getValue() instanceof ContainerNode);
- final ContainerNode actualNode = (ContainerNode) capturedNode.getValue();
- assertEquals("ContainerNode node type", TEST_CONT1_QNAME, actualNode.getIdentifier().getNodeType());
- verifyLeafNode(actualNode, TEST_LF11_QNAME, "lf11 data");
- verifyLeafNode(actualNode, TEST_LF12_QNAME, "lf12 data");
- }
-
- @Test(expected = OperationFailedException.class)
- @SuppressWarnings("checkstyle:IllegalThrows")
- public void testPutFailure() throws Throwable {
- final PutResult result = mock(PutResult.class);
-
- doReturn(immediateFailedFluentFuture(new TransactionCommitFailedException("mock"))).when(result)
- .getFutureOfPutData();
- when(result.getStatus()).thenReturn(Status.OK);
- when(brokerFacade.commitConfigurationDataPut(any(EffectiveModelContext.class),
- any(YangInstanceIdentifier.class), any(NormalizedNode.class), anyString(),
- anyString())).thenReturn(result);
-
- final String uriPath = "ietf-interfaces:interfaces/interface/eth0";
- final String payload = loadData("/parts/ietf-interfaces_interfaces.json");
-
- service.put(uriPath, payload);
- }
-
- @Test
- public void testPost() throws Exception {
- doReturn(CommitInfo.emptyFluentFuture()).when(brokerFacade).commitConfigurationDataPost(
- any(EffectiveModelContext.class), any(YangInstanceIdentifier.class), any(NormalizedNode.class),
- isNull(), isNull());
-
- final String uriPath = null;
- final String payload = loadData("/parts/ietf-interfaces_interfaces_absolute_path.json");
-
- service.post(uriPath, payload);
-
- final ArgumentCaptor<YangInstanceIdentifier> capturedPath =
- ArgumentCaptor.forClass(YangInstanceIdentifier.class);
- final ArgumentCaptor<NormalizedNode> capturedNode = ArgumentCaptor.forClass(NormalizedNode.class);
- verify(brokerFacade).commitConfigurationDataPost(any(EffectiveModelContext.class), capturedPath.capture(),
- capturedNode.capture(), isNull(), isNull());
-
- verifyPath(capturedPath.getValue(), INTERFACES_QNAME);
-
- assertTrue("Expected ContainerNode", capturedNode.getValue() instanceof ContainerNode);
- final ContainerNode actualNode = (ContainerNode) capturedNode.getValue();
- assertEquals("ContainerNode node type", INTERFACES_QNAME, actualNode.getIdentifier().getNodeType());
-
- final java.util.Optional<DataContainerChild> mapChild = actualNode.findChildByArg(
- new NodeIdentifier(INTERFACE_QNAME));
- assertEquals(INTERFACE_QNAME.toString() + " present", true, mapChild.isPresent());
- assertTrue("Expected MapNode. Actual " + mapChild.get().getClass(), mapChild.get() instanceof MapNode);
- final MapNode mapNode = (MapNode)mapChild.get();
-
- final NodeIdentifierWithPredicates entryNodeID = NodeIdentifierWithPredicates.of(
- INTERFACE_QNAME, NAME_QNAME, "eth0");
- final java.util.Optional<MapEntryNode> entryChild = mapNode.findChildByArg(entryNodeID);
- assertEquals(entryNodeID.toString() + " present", true, entryChild.isPresent());
- final MapEntryNode entryNode = entryChild.get();
- verifyLeafNode(entryNode, NAME_QNAME, "eth0");
- verifyLeafNode(entryNode, TYPE_QNAME, "ethernetCsmacd");
- verifyLeafNode(entryNode, ENABLED_QNAME, Boolean.FALSE);
- verifyLeafNode(entryNode, DESC_QNAME, "some interface");
- }
-
- @Test
- public void testPostBehindMountPoint() throws Exception {
- doReturn(CommitInfo.emptyFluentFuture()).when(brokerFacade).commitConfigurationDataPost(
- any(DOMMountPoint.class), any(YangInstanceIdentifier.class), any(NormalizedNode.class),
- isNull(), isNull());
-
- final String uriPath = "ietf-interfaces:interfaces/yang-ext:mount/test-module:cont";
- final String payload = loadData("/full-versions/testCont1Data.json");
-
- service.post(uriPath, payload);
-
- final ArgumentCaptor<YangInstanceIdentifier> capturedPath =
- ArgumentCaptor.forClass(YangInstanceIdentifier.class);
- final ArgumentCaptor<NormalizedNode> capturedNode = ArgumentCaptor.forClass(NormalizedNode.class);
- verify(brokerFacade).commitConfigurationDataPost(same(mockMountPoint), capturedPath.capture(),
- capturedNode.capture(), isNull(), isNull());
-
- verifyPath(capturedPath.getValue(), TEST_CONT_QNAME, TEST_CONT1_QNAME);
-
- assertTrue("Expected ContainerNode", capturedNode.getValue() instanceof ContainerNode);
- final ContainerNode actualNode = (ContainerNode) capturedNode.getValue();
- assertEquals("ContainerNode node type", TEST_CONT1_QNAME, actualNode.getIdentifier().getNodeType());
- verifyLeafNode(actualNode, TEST_LF11_QNAME, "lf11 data");
- verifyLeafNode(actualNode, TEST_LF12_QNAME, "lf12 data");
- }
-
- @Test(expected = TransactionCommitFailedException.class)
- @SuppressWarnings({ "checkstyle:IllegalThrows", "checkstyle:avoidHidingCauseException" })
- public void testPostFailure() throws Throwable {
- doReturn(immediateFailedFluentFuture(new TransactionCommitFailedException("mock"))).when(brokerFacade)
- .commitConfigurationDataPost(any(EffectiveModelContext.class), any(YangInstanceIdentifier.class),
- any(NormalizedNode.class), isNull(), isNull());
-
- final String uriPath = null;
- final String payload = loadData("/parts/ietf-interfaces_interfaces_absolute_path.json");
-
- try {
- service.post(uriPath, payload);
- } catch (final OperationFailedException e) {
- assertNotNull(e.getCause());
- throw e.getCause();
- }
- }
-
- @Test
- public void testPatch() throws Exception {
- final PatchStatusContext result = mock(PatchStatusContext.class);
- when(brokerFacade.patchConfigurationDataWithinTransaction(any(PatchContext.class)))
- .thenReturn(result);
-
- when(result.getEditCollection()).thenReturn(List.of(new PatchStatusEntity("edit1", true, null)));
- when(result.getGlobalErrors()).thenReturn(List.of());
- when(result.getPatchId()).thenReturn("1");
- final String uriPath = "ietf-interfaces:interfaces/interface/eth0";
- final String payload = loadData("/parts/ietf-interfaces_interfaces_patch.json");
- final Optional<String> patchResult = service.patch(uriPath, payload);
-
- assertTrue(patchResult.get().contains("\"ok\":[null]"));
- }
-
- @Test
- public void testPatchBehindMountPoint() throws Exception {
- final PatchStatusContext result = mock(PatchStatusContext.class);
- when(brokerFacade.patchConfigurationDataWithinTransaction(any(PatchContext.class))).thenReturn(result);
-
- when(result.getEditCollection()).thenReturn(List.of(new PatchStatusEntity("edit1", true, null)));
- when(result.getGlobalErrors()).thenReturn(List.of());
- when(result.getPatchId()).thenReturn("1");
-
- final String uriPath = "ietf-interfaces:interfaces/yang-ext:mount/test-module:cont/cont1";
- final String payload = loadData("/full-versions/testCont1DataPatch.json");
-
- final Optional<String> patchResult = service.patch(uriPath, payload);
-
- assertTrue(patchResult.get().contains("\"ok\":[null]"));
- }
-
- @Test(expected = OperationFailedException.class)
- @SuppressWarnings("checkstyle:IllegalThrows")
- public void testPatchFailure() throws Throwable {
- final PatchStatusContext result = mock(PatchStatusContext.class);
- when(brokerFacade.patchConfigurationDataWithinTransaction(any(PatchContext.class)))
- .thenThrow(new TransactionCommitFailedException("Transaction failed"));
-
- final String uriPath = "ietf-interfaces:interfaces/interface/eth0";
- final String payload = loadData("/parts/ietf-interfaces_interfaces_patch.json");
-
- final Optional<String> patchResult = service.patch(uriPath, payload);
-
- assertTrue("Patch output is not null", patchResult.isPresent());
- String patch = patchResult.get();
- assertTrue(patch.contains("TransactionCommitFailedException"));
- }
-
- @Test
- public void testDelete() throws Exception {
- doReturn(CommitInfo.emptyFluentFuture()).when(brokerFacade)
- .commitConfigurationDataDelete(any(YangInstanceIdentifier.class));
-
- final String uriPath = "ietf-interfaces:interfaces/interface/eth0";
-
- service.delete(uriPath);
-
- final ArgumentCaptor<YangInstanceIdentifier> capturedPath =
- ArgumentCaptor.forClass(YangInstanceIdentifier.class);
- verify(brokerFacade).commitConfigurationDataDelete(capturedPath.capture());
-
- verifyPath(capturedPath.getValue(), INTERFACES_QNAME, INTERFACE_QNAME,
- new Object[]{INTERFACE_QNAME, NAME_QNAME, "eth0"});
- }
-
- @Test(expected = OperationFailedException.class)
- public void testDeleteFailure() throws Exception {
- final String invalidUriPath = "ietf-interfaces:interfaces/invalid";
-
- service.delete(invalidUriPath);
- }
-
- @Test
- public void testGetConfig() throws Exception {
- testGet(LogicalDatastoreType.CONFIGURATION);
- }
-
- @Test
- public void testGetOperational() throws Exception {
- testGet(LogicalDatastoreType.OPERATIONAL);
- }
-
- @Test
- public void testGetWithNoData() throws OperationFailedException {
- doReturn(null).when(brokerFacade).readConfigurationData(any(YangInstanceIdentifier.class), anyString());
- final String uriPath = "ietf-interfaces:interfaces";
- service.get(uriPath, LogicalDatastoreType.CONFIGURATION);
- }
-
- @Test(expected = OperationFailedException.class)
- public void testGetFailure() throws Exception {
- final String invalidUriPath = "/ietf-interfaces:interfaces/invalid";
- service.get(invalidUriPath, LogicalDatastoreType.CONFIGURATION);
- }
-
- @Test
- public void testInvokeRpcWithInput() throws Exception {
- final DOMRpcResult expResult = new DefaultDOMRpcResult((NormalizedNode)null);
- doReturn(immediateFluentFuture(expResult)).when(brokerFacade).invokeRpc(eq(MAKE_TOAST_QNAME),
- any(NormalizedNode.class));
-
- final String uriPath = "toaster:make-toast";
- final String input = loadData("/full-versions/make-toast-rpc-input.json");
-
- final Optional<String> output = service.invokeRpc(uriPath, Optional.of(input));
-
- assertEquals("Output present", false, output.isPresent());
-
- final ArgumentCaptor<NormalizedNode> capturedNode = ArgumentCaptor.forClass(NormalizedNode.class);
- verify(brokerFacade).invokeRpc(eq(MAKE_TOAST_QNAME), capturedNode.capture());
-
- assertTrue("Expected ContainerNode. Actual " + capturedNode.getValue().getClass(),
- capturedNode.getValue() instanceof ContainerNode);
- final ContainerNode actualNode = (ContainerNode) capturedNode.getValue();
- verifyLeafNode(actualNode, TOASTER_DONENESS_QNAME, Uint32.valueOf(10));
- verifyLeafNode(actualNode, TOASTER_TYPE_QNAME, WHEAT_BREAD_QNAME);
- }
-
- @Test
- public void testInvokeRpcWithNoInput() throws Exception {
- final DOMRpcResult expResult = new DefaultDOMRpcResult((NormalizedNode)null);
- doReturn(immediateFluentFuture(expResult)).when(brokerFacade).invokeRpc(any(QName.class), any());
-
- final String uriPath = "toaster:cancel-toast";
-
- final Optional<String> output = service.invokeRpc(uriPath, Optional.empty());
-
- assertEquals("Output present", false, output.isPresent());
-
- verify(brokerFacade).invokeRpc(eq(CANCEL_TOAST_QNAME), any());
- }
-
- @Test
- public void testInvokeRpcWithOutput() throws Exception {
- final NormalizedNode outputNode = ImmutableContainerNodeBuilder.create()
- .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TEST_OUTPUT_QNAME))
- .withChild(ImmutableNodes.leafNode(TEXT_OUT_QNAME, "foo")).build();
- final DOMRpcResult expResult = new DefaultDOMRpcResult(outputNode);
- doReturn(immediateFluentFuture(expResult)).when(brokerFacade).invokeRpc(any(QName.class), any());
-
- final String uriPath = "toaster:testOutput";
-
- final Optional<String> output = service.invokeRpc(uriPath, Optional.empty());
-
- assertEquals("Output present", true, output.isPresent());
- assertNotNull("Returned null response", output.get());
- assertThat("Missing \"textOut\"", output.get(), containsString("\"textOut\":\"foo\""));
-
- verify(brokerFacade).invokeRpc(eq(TEST_OUTPUT_QNAME), any());
- }
-
- @Test(expected = OperationFailedException.class)
- public void testInvokeRpcFailure() throws Exception {
- final DOMRpcException exception = new DOMRpcImplementationNotAvailableException("testExeption");
- doReturn(immediateFailedFluentFuture(exception)).when(brokerFacade).invokeRpc(any(QName.class),
- any(NormalizedNode.class));
-
- final String uriPath = "toaster:cancel-toast";
-
- service.invokeRpc(uriPath, Optional.empty());
- }
-
- void testGet(final LogicalDatastoreType datastoreType) throws OperationFailedException {
- final MapEntryNode entryNode = ImmutableNodes.mapEntryBuilder(INTERFACE_QNAME, NAME_QNAME, "eth0")
- .withChild(ImmutableNodes.leafNode(NAME_QNAME, "eth0"))
- .withChild(ImmutableNodes.leafNode(TYPE_QNAME, "ethernetCsmacd"))
- .withChild(ImmutableNodes.leafNode(ENABLED_QNAME, Boolean.TRUE))
- .withChild(ImmutableNodes.leafNode(DESC_QNAME, "eth interface"))
- .build();
-
- if (datastoreType == LogicalDatastoreType.CONFIGURATION) {
- doReturn(entryNode).when(brokerFacade).readConfigurationData(any(YangInstanceIdentifier.class),
- isNull());
- } else {
- doReturn(entryNode).when(brokerFacade).readOperationalData(any(YangInstanceIdentifier.class));
- }
-
- final String uriPath = "/ietf-interfaces:interfaces/interface/eth0";
-
- final Optional<String> optionalResp = service.get(uriPath, datastoreType);
- assertEquals("Response present", true, optionalResp.isPresent());
- final String jsonResp = optionalResp.get();
-
- assertNotNull("Returned null response", jsonResp);
- assertThat("Missing \"name\"", jsonResp, containsString("\"name\":\"eth0\""));
- assertThat("Missing \"type\"", jsonResp, containsString("\"type\":\"ethernetCsmacd\""));
- assertThat("Missing \"enabled\"", jsonResp, containsString("\"enabled\":true"));
- assertThat("Missing \"description\"", jsonResp, containsString("\"description\":\"eth interface\""));
-
- final ArgumentCaptor<YangInstanceIdentifier> capturedPath =
- ArgumentCaptor.forClass(YangInstanceIdentifier.class);
- if (datastoreType == LogicalDatastoreType.CONFIGURATION) {
- verify(brokerFacade).readConfigurationData(capturedPath.capture(), isNull());
- } else {
- verify(brokerFacade).readOperationalData(capturedPath.capture());
- }
-
- verifyPath(capturedPath.getValue(), INTERFACES_QNAME, INTERFACE_QNAME,
- new Object[]{INTERFACE_QNAME, NAME_QNAME, "eth0"});
- }
-
- void verifyLeafNode(final DataContainerNode parent, final QName leafType, final Object leafValue) {
- final java.util.Optional<DataContainerChild> leafChild = parent.findChildByArg(new NodeIdentifier(leafType));
- assertTrue(leafType.toString() + " present", leafChild.isPresent());
- assertEquals(leafType.toString() + " value", leafValue, leafChild.get().body());
- }
-
- void verifyPath(final YangInstanceIdentifier path, final Object... expArgs) {
- final List<PathArgument> pathArgs = path.getPathArguments();
- assertEquals("Arg count for actual path " + path, expArgs.length, pathArgs.size());
- int index = 0;
- for (final PathArgument actual: pathArgs) {
- QName expNodeType;
- if (expArgs[index] instanceof Object[]) {
- final Object[] listEntry = (Object[]) expArgs[index];
- expNodeType = (QName) listEntry[0];
-
- assertTrue(actual instanceof NodeIdentifierWithPredicates);
- final NodeIdentifierWithPredicates nip = (NodeIdentifierWithPredicates)actual;
- assertEquals(String.format("Path arg %d keyValues size", index + 1), 1, nip.size());
- final QName expKey = (QName) listEntry[1];
- assertEquals(String.format("Path arg %d keyValue for %s", index + 1, expKey), listEntry[2],
- nip.getValue(expKey));
- } else {
- expNodeType = (QName) expArgs[index];
- }
-
- assertEquals(String.format("Path arg %d node type", index + 1), expNodeType, actual.getNodeType());
- index++;
- }
-
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.JSON;
-import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.UriInfo;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.BeforeClass;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.opendaylight.netconf.sal.rest.api.Draft02;
-import org.opendaylight.netconf.sal.rest.api.RestconfService;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeJsonBodyWriter;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeXmlBodyWriter;
-
-public class MediaTypesTest extends JerseyTest {
-
- private static String jsonData;
- private static String xmlData;
-
- private RestconfService restconfService;
-
- @BeforeClass
- public static void init() throws IOException {
- final String jsonPath = RestconfImplTest.class.getResource("/parts/ietf-interfaces_interfaces.json").getPath();
- jsonData = TestUtils.loadTextFile(jsonPath);
- final InputStream xmlStream =
- RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
- xmlData = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
- }
-
- @Override
- protected Application configure() {
- /* enable/disable Jersey logs to console */
- // enable(TestProperties.LOG_TRAFFIC);
- // enable(TestProperties.DUMP_ENTITY);
- // enable(TestProperties.RECORD_LOG_LEVEL);
- // set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());'
- restconfService = mock(RestconfService.class);
- ResourceConfig resourceConfig = new ResourceConfig();
- resourceConfig = resourceConfig.registerInstances(restconfService, new NormalizedNodeJsonBodyWriter(),
- new NormalizedNodeXmlBodyWriter());
- return resourceConfig;
- }
-
- @Test
- @Ignore
- public void testPostOperationsWithInputDataMediaTypes() throws UnsupportedEncodingException {
- final String uriPrefix = "/operations/";
- final String uriPath = "ietf-interfaces:interfaces";
- final String uri = uriPrefix + uriPath;
- when(restconfService.invokeRpc(eq(uriPath), any(NormalizedNodeContext.class), any(UriInfo.class)))
- .thenReturn(null);
- post(uri, Draft02.MediaTypes.OPERATION + JSON, Draft02.MediaTypes.OPERATION + JSON, jsonData);
- verify(restconfService, times(1)).invokeRpc(eq(uriPath), any(NormalizedNodeContext.class), any(UriInfo.class));
- post(uri, Draft02.MediaTypes.OPERATION + XML, Draft02.MediaTypes.OPERATION + XML, xmlData);
- verify(restconfService, times(2)).invokeRpc(eq(uriPath), any(NormalizedNodeContext.class), any(UriInfo.class));
- post(uri, MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON, jsonData);
- verify(restconfService, times(3)).invokeRpc(eq(uriPath), any(NormalizedNodeContext.class), any(UriInfo.class));
- post(uri, MediaType.APPLICATION_XML, MediaType.APPLICATION_XML, xmlData);
- verify(restconfService, times(4)).invokeRpc(eq(uriPath), any(NormalizedNodeContext.class), any(UriInfo.class));
- post(uri, MediaType.TEXT_XML, MediaType.TEXT_XML, xmlData);
- verify(restconfService, times(5)).invokeRpc(eq(uriPath), any(NormalizedNodeContext.class), any(UriInfo.class));
- post(uri, null, MediaType.TEXT_XML, xmlData);
- verify(restconfService, times(6)).invokeRpc(eq(uriPath), any(NormalizedNodeContext.class), any(UriInfo.class));
-
- // negative tests
- post(uri, MediaType.TEXT_PLAIN, MediaType.TEXT_XML, xmlData);
- verify(restconfService, times(6)).invokeRpc(eq(uriPath), any(NormalizedNodeContext.class), any(UriInfo.class));
- post(uri, MediaType.TEXT_XML, MediaType.TEXT_PLAIN, xmlData);
- verify(restconfService, times(6)).invokeRpc(eq(uriPath), any(NormalizedNodeContext.class), any(UriInfo.class));
- }
-
- @Test
- public void testGetConfigMediaTypes() throws UnsupportedEncodingException {
- final String uriPrefix = "/config/";
- final String uriPath = "ietf-interfaces:interfaces";
- final String uri = uriPrefix + uriPath;
- when(restconfService.readConfigurationData(eq(uriPath), any(UriInfo.class))).thenReturn(null);
- get(uri, Draft02.MediaTypes.DATA + JSON);
- verify(restconfService, times(1)).readConfigurationData(eq(uriPath), any(UriInfo.class));
- get(uri, Draft02.MediaTypes.DATA + XML);
- verify(restconfService, times(2)).readConfigurationData(eq(uriPath), any(UriInfo.class));
- get(uri, MediaType.APPLICATION_JSON);
- verify(restconfService, times(3)).readConfigurationData(eq(uriPath), any(UriInfo.class));
- get(uri, MediaType.APPLICATION_XML);
- verify(restconfService, times(4)).readConfigurationData(eq(uriPath), any(UriInfo.class));
- get(uri, MediaType.TEXT_XML);
- verify(restconfService, times(5)).readConfigurationData(eq(uriPath), any(UriInfo.class));
-
- // negative tests
- get(uri, MediaType.TEXT_PLAIN);
- verify(restconfService, times(5)).readConfigurationData(eq(uriPath), any(UriInfo.class));
- }
-
- @Test
- public void testGetOperationalMediaTypes() throws UnsupportedEncodingException {
- final String uriPrefix = "/operational/";
- final String uriPath = "ietf-interfaces:interfaces";
- final String uri = uriPrefix + uriPath;
- when(restconfService.readOperationalData(eq(uriPath), any(UriInfo.class))).thenReturn(null);
- get(uri, Draft02.MediaTypes.DATA + JSON);
- verify(restconfService, times(1)).readOperationalData(eq(uriPath), any(UriInfo.class));
- get(uri, Draft02.MediaTypes.DATA + XML);
- verify(restconfService, times(2)).readOperationalData(eq(uriPath), any(UriInfo.class));
- get(uri, MediaType.APPLICATION_JSON);
- verify(restconfService, times(3)).readOperationalData(eq(uriPath), any(UriInfo.class));
- get(uri, MediaType.APPLICATION_XML);
- verify(restconfService, times(4)).readOperationalData(eq(uriPath), any(UriInfo.class));
- get(uri, MediaType.TEXT_XML);
- verify(restconfService, times(5)).readOperationalData(eq(uriPath), any(UriInfo.class));
-
- // negative tests
- get(uri, MediaType.TEXT_PLAIN);
- verify(restconfService, times(5)).readOperationalData(eq(uriPath), any(UriInfo.class));
- }
-
- @Test
- @Ignore
- public void testPutConfigMediaTypes() throws UnsupportedEncodingException {
- final String uriPrefix = "/config/";
- final String uriPath = "ietf-interfaces:interfaces";
- final String uri = uriPrefix + uriPath;
- final UriInfo uriInfo = Mockito.mock(UriInfo.class);
- when(restconfService.updateConfigurationData(eq(uriPath), any(NormalizedNodeContext.class), uriInfo))
- .thenReturn(null);
- put(uri, null, Draft02.MediaTypes.DATA + JSON, jsonData);
- verify(restconfService, times(1)).updateConfigurationData(eq(uriPath), any(NormalizedNodeContext.class),
- uriInfo);
- put(uri, null, Draft02.MediaTypes.DATA + XML, xmlData);
- verify(restconfService, times(2)).updateConfigurationData(eq(uriPath), any(NormalizedNodeContext.class),
- uriInfo);
- put(uri, null, MediaType.APPLICATION_JSON, jsonData);
- verify(restconfService, times(3)).updateConfigurationData(eq(uriPath), any(NormalizedNodeContext.class),
- uriInfo);
- put(uri, null, MediaType.APPLICATION_XML, xmlData);
- verify(restconfService, times(4)).updateConfigurationData(eq(uriPath), any(NormalizedNodeContext.class),
- uriInfo);
- put(uri, null, MediaType.TEXT_XML, xmlData);
- verify(restconfService, times(5)).updateConfigurationData(eq(uriPath), any(NormalizedNodeContext.class),
- uriInfo);
- put(uri, "fooMediaType", MediaType.TEXT_XML, xmlData);
- verify(restconfService, times(6)).updateConfigurationData(eq(uriPath), any(NormalizedNodeContext.class),
- uriInfo);
- }
-
- @Test
- @Ignore
- public void testPostConfigWithPathMediaTypes() throws UnsupportedEncodingException {
- final String uriPrefix = "/config/";
- final String uriPath = "ietf-interfaces:interfaces";
- final String uri = uriPrefix + uriPath;
- when(restconfService.createConfigurationData(eq(uriPath), any(NormalizedNodeContext.class),
- any(UriInfo.class))).thenReturn(null);
- post(uri, null, Draft02.MediaTypes.DATA + JSON, jsonData);
- verify(restconfService, times(1)).createConfigurationData(eq(uriPath),
- any(NormalizedNodeContext.class), any(UriInfo.class));
- post(uri, null, Draft02.MediaTypes.DATA + XML, xmlData);
- verify(restconfService, times(2)).createConfigurationData(eq(uriPath),
- any(NormalizedNodeContext.class), any(UriInfo.class));
- post(uri, null, MediaType.APPLICATION_JSON, jsonData);
- verify(restconfService, times(3)).createConfigurationData(eq(uriPath),
- any(NormalizedNodeContext.class), any(UriInfo.class));
- post(uri, null, MediaType.APPLICATION_XML, xmlData);
- verify(restconfService, times(4)).createConfigurationData(eq(uriPath),
- any(NormalizedNodeContext.class), any(UriInfo.class));
- post(uri, null, MediaType.TEXT_XML, xmlData);
- verify(restconfService, times(5)).createConfigurationData(eq(uriPath),
- any(NormalizedNodeContext.class), any(UriInfo.class));
- post(uri, "fooMediaType", MediaType.TEXT_XML, xmlData);
- verify(restconfService, times(6)).createConfigurationData(eq(uriPath),
- any(NormalizedNodeContext.class), any(UriInfo.class));
- }
-
- @Test
- @Ignore
- public void testPostConfigMediaTypes() throws UnsupportedEncodingException {
- final String uriPrefix = "/config/";
- final String uri = uriPrefix;
- when(restconfService.createConfigurationData(any(NormalizedNodeContext.class),
- any(UriInfo.class))).thenReturn(null);
- post(uri, null, Draft02.MediaTypes.DATA + JSON, jsonData);
- verify(restconfService, times(1)).createConfigurationData(
- any(NormalizedNodeContext.class), any(UriInfo.class));
- post(uri, null, Draft02.MediaTypes.DATA + XML, xmlData);
- verify(restconfService, times(2)).createConfigurationData(
- any(NormalizedNodeContext.class), any(UriInfo.class));
- post(uri, null, MediaType.APPLICATION_JSON, jsonData);
- verify(restconfService, times(3)).createConfigurationData(
- any(NormalizedNodeContext.class), any(UriInfo.class));
- post(uri, null, MediaType.APPLICATION_XML, xmlData);
- verify(restconfService, times(4)).createConfigurationData(
- any(NormalizedNodeContext.class), any(UriInfo.class));
- post(uri, null, MediaType.TEXT_XML, xmlData);
- verify(restconfService, times(5)).createConfigurationData(
- any(NormalizedNodeContext.class), any(UriInfo.class));
- post(uri, "fooMediaType", MediaType.TEXT_XML, xmlData);
- verify(restconfService, times(6)).createConfigurationData(
- any(NormalizedNodeContext.class), any(UriInfo.class));
- }
-
- @Test
- public void testDeleteConfigMediaTypes() throws UnsupportedEncodingException {
- final String uriPrefix = "/config/";
- final String uriPath = "ietf-interfaces:interfaces";
- final String uri = uriPrefix + uriPath;
- when(restconfService.deleteConfigurationData(eq(uriPath))).thenReturn(null);
- target(uri).request("fooMediaType").delete();
- verify(restconfService, times(1)).deleteConfigurationData(uriPath);
- }
-
- private int get(final String uri, final String acceptMediaType) {
- return target(uri).request(acceptMediaType).get().getStatus();
- }
-
- private int put(final String uri, final String acceptMediaType, final String contentTypeMediaType,
- final String data) {
- if (acceptMediaType == null) {
- return target(uri).request().put(Entity.entity(data, contentTypeMediaType)).getStatus();
- }
- return target(uri).request(acceptMediaType).put(Entity.entity(data, contentTypeMediaType)).getStatus();
- }
-
- private int post(final String uri, final String acceptMediaType, final String contentTypeMediaType,
- final String data) {
- if (acceptMediaType == null) {
- if (contentTypeMediaType == null || data == null) {
- return target(uri).request().post(null).getStatus();
- }
- return target(uri).request().post(Entity.entity(data, contentTypeMediaType)).getStatus();
- }
- if (contentTypeMediaType == null || data == null) {
- return target(uri).request(acceptMediaType).post(null).getStatus();
- }
- return target(uri).request(acceptMediaType).post(Entity.entity(data, contentTypeMediaType)).getStatus();
- }
-
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-import java.io.FileNotFoundException;
-import org.junit.BeforeClass;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
-
-public class NormalizeNodeTest extends YangAndXmlAndDataSchemaLoader {
-
- @BeforeClass
- public static void initialization() throws FileNotFoundException, ReactorException {
- dataLoad("/normalize-node/yang/");
- }
-
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.mock;
-
-import org.junit.Test;
-import org.opendaylight.netconf.sal.restconf.impl.RestCodec;
-import org.opendaylight.yangtools.concepts.IllegalArgumentCodec;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
-import org.opendaylight.yangtools.yang.model.ri.type.BaseTypes;
-
-public class RestCodecExceptionsTest {
- @Test
- public void serializeExceptionTest() {
- final IllegalArgumentCodec<Object, Object> codec = RestCodec.from(
- BaseTypes.bitsTypeBuilder(QName.create("test", "2014-05-30", "test")).build(), null, null);
- final String serializedValue = (String) codec.serialize("incorrect value"); // set
- // expected
- assertEquals("incorrect value", serializedValue);
- }
-
- @Test
- public void deserializeExceptionTest() {
- final IdentityrefTypeDefinition mockedIidentityrefType = mock(IdentityrefTypeDefinition.class);
-
- final IllegalArgumentCodec<Object, Object> codec = RestCodec.from(mockedIidentityrefType, null, null);
- assertNull(codec.deserialize("incorrect value"));
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFailedFluentFuture;
-
-import java.io.FileNotFoundException;
-import java.io.UnsupportedEncodingException;
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
-import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeJsonBodyWriter;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeXmlBodyWriter;
-import org.opendaylight.netconf.sal.rest.impl.RestconfDocumentedExceptionMapper;
-import org.opendaylight.netconf.sal.rest.impl.XmlNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.restconf.impl.BrokerFacade;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.netconf.sal.restconf.impl.RestconfImpl;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
-
-public class RestDeleteOperationTest extends JerseyTest {
- private static EffectiveModelContext schemaContext;
-
- private ControllerContext controllerContext;
- private BrokerFacade brokerFacade;
- private RestconfImpl restconfImpl;
-
- @BeforeClass
- public static void init() throws FileNotFoundException, ReactorException {
- schemaContext = TestUtils.loadSchemaContext("/test-config-data/yang1");
- }
-
- @Override
- protected Application configure() {
- /* enable/disable Jersey logs to console */
- // enable(TestProperties.LOG_TRAFFIC);
- // enable(TestProperties.DUMP_ENTITY);
- // enable(TestProperties.RECORD_LOG_LEVEL);
- // set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
- controllerContext = TestRestconfUtils.newControllerContext(schemaContext);
- controllerContext.setSchemas(schemaContext);
- brokerFacade = mock(BrokerFacade.class);
- restconfImpl = RestconfImpl.newInstance(brokerFacade, controllerContext);
-
- ResourceConfig resourceConfig = new ResourceConfig();
- resourceConfig = resourceConfig.registerInstances(restconfImpl, new NormalizedNodeJsonBodyWriter(),
- new NormalizedNodeXmlBodyWriter(), new XmlNormalizedNodeBodyReader(controllerContext),
- new JsonNormalizedNodeBodyReader(controllerContext),
- new RestconfDocumentedExceptionMapper(controllerContext));
- return resourceConfig;
- }
-
- @Test
- public void deleteConfigStatusCodes() throws UnsupportedEncodingException {
- final String uri = "/config/test-interface:interfaces";
- doReturn(CommitInfo.emptyFluentFuture()).when(brokerFacade)
- .commitConfigurationDataDelete(any(YangInstanceIdentifier.class));
- Response response = target(uri).request(MediaType.APPLICATION_XML).delete();
- assertEquals(200, response.getStatus());
-
- doThrow(RestconfDocumentedException.class).when(brokerFacade).commitConfigurationDataDelete(
- any(YangInstanceIdentifier.class));
- response = target(uri).request(MediaType.APPLICATION_XML).delete();
- assertEquals(500, response.getStatus());
- }
-
- @Test
- public void deleteFailTest() throws Exception {
- final String uri = "/config/test-interface:interfaces";
- doReturn(immediateFailedFluentFuture(new TransactionCommitFailedException("failed test"))).when(brokerFacade)
- .commitConfigurationDataDelete(any(YangInstanceIdentifier.class));
- final Response response = target(uri).request(MediaType.APPLICATION_XML).delete();
- assertEquals(500, response.getStatus());
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThrows;
-
-import java.io.FileNotFoundException;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.yangtools.yang.common.XMLNamespace;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-
-public class RestGetAugmentedElementWhenEqualNamesTest {
-
- private static EffectiveModelContext schemaContext;
-
- private final ControllerContext controllerContext = TestRestconfUtils.newControllerContext(schemaContext);
-
- @BeforeClass
- public static void init() throws FileNotFoundException {
- schemaContext = TestUtils.loadSchemaContext("/common/augment/yang");
- }
-
- @Test
- public void augmentedNodesInUri() {
- InstanceIdentifierContext iiWithData =
- controllerContext.toInstanceIdentifier("main:cont/augment-main-a:cont1");
- assertEquals(XMLNamespace.of("ns:augment:main:a"), iiWithData.getSchemaNode().getQName().getNamespace());
- iiWithData = controllerContext.toInstanceIdentifier("main:cont/augment-main-b:cont1");
- assertEquals(XMLNamespace.of("ns:augment:main:b"), iiWithData.getSchemaNode().getQName().getNamespace());
- }
-
- @Test
- public void nodeWithoutNamespaceHasMoreAugments() {
- final var ex = assertThrows(RestconfDocumentedException.class,
- () -> controllerContext.toInstanceIdentifier("main:cont/cont1"));
- assertThat(ex.getErrors().get(0).getErrorMessage(),
- containsString("is added as augment from more than one module"));
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import com.google.common.collect.ImmutableMap;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedHashMap;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.BeforeClass;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.mdsal.dom.api.DOMMountPoint;
-import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
-import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeJsonBodyWriter;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeXmlBodyWriter;
-import org.opendaylight.netconf.sal.rest.impl.RestconfDocumentedExceptionMapper;
-import org.opendaylight.netconf.sal.rest.impl.XmlNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.restconf.impl.BrokerFacade;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.netconf.sal.restconf.impl.RestconfImpl;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-public class RestGetOperationTest extends JerseyTest {
-
- static class NodeData {
- Object key;
- Object data; // List for a CompositeNode, value Object for a SimpleNode
-
- NodeData(final Object key, final Object data) {
- this.key = key;
- this.data = data;
- }
- }
-
- private static EffectiveModelContext schemaContextYangsIetf;
- private static EffectiveModelContext schemaContextTestModule;
- private static EffectiveModelContext schemaContextModules;
- private static EffectiveModelContext schemaContextBehindMountPoint;
-
- private static NormalizedNode answerFromGet;
-
- private BrokerFacade brokerFacade;
- private RestconfImpl restconfImpl;
- private ControllerContext controllerContext;
- private DOMMountPoint mountInstance;
-
- private static final String RESTCONF_NS = "urn:ietf:params:xml:ns:yang:ietf-restconf";
-
- @BeforeClass
- public static void init() throws Exception {
- schemaContextYangsIetf = TestUtils.loadSchemaContext("/full-versions/yangs");
- schemaContextTestModule = TestUtils.loadSchemaContext("/full-versions/test-module");
- schemaContextModules = TestUtils.loadSchemaContext("/modules");
- schemaContextBehindMountPoint = TestUtils.loadSchemaContext("/modules/modules-behind-mount-point");
-
- answerFromGet = TestUtils.prepareNormalizedNodeWithIetfInterfacesInterfacesData();
- }
-
- @Override
- protected Application configure() {
- /* enable/disable Jersey logs to console */
- // enable(TestProperties.LOG_TRAFFIC);
- // enable(TestProperties.DUMP_ENTITY);
- // enable(TestProperties.RECORD_LOG_LEVEL);
- // set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
-
- mountInstance = mock(DOMMountPoint.class);
- controllerContext = TestRestconfUtils.newControllerContext(schemaContextYangsIetf, mountInstance);
- brokerFacade = mock(BrokerFacade.class);
- restconfImpl = RestconfImpl.newInstance(brokerFacade, controllerContext);
-
- ResourceConfig resourceConfig = new ResourceConfig();
- resourceConfig = resourceConfig.registerInstances(restconfImpl, new NormalizedNodeJsonBodyWriter(),
- new NormalizedNodeXmlBodyWriter(), new XmlNormalizedNodeBodyReader(controllerContext),
- new JsonNormalizedNodeBodyReader(controllerContext),
- new RestconfDocumentedExceptionMapper(controllerContext));
- return resourceConfig;
- }
-
- private void setControllerContext(final EffectiveModelContext schemaContext) {
- controllerContext.setSchemas(schemaContext);
- }
-
- /**
- * Tests of status codes for "/operational/{identifier}".
- */
- @Test
- public void getOperationalStatusCodes() throws Exception {
- setControllerContext(schemaContextYangsIetf);
- mockReadOperationalDataMethod();
- String uri = "/operational/ietf-interfaces:interfaces/interface/eth0";
- assertEquals(200, get(uri, MediaType.APPLICATION_XML));
-
- uri = "/operational/wrong-module:interfaces/interface/eth0";
- assertEquals(400, get(uri, MediaType.APPLICATION_XML));
- }
-
- /**
- * Tests of status codes for "/config/{identifier}".
- */
- @Test
- public void getConfigStatusCodes() throws Exception {
- setControllerContext(schemaContextYangsIetf);
- mockReadConfigurationDataMethod();
- String uri = "/config/ietf-interfaces:interfaces/interface/eth0";
- assertEquals(200, get(uri, MediaType.APPLICATION_XML));
-
- uri = "/config/wrong-module:interfaces/interface/eth0";
- assertEquals(400, get(uri, MediaType.APPLICATION_XML));
- }
-
- /**
- * MountPoint test. URI represents mount point.
- */
- @Test
- public void getDataWithUrlMountPoint() throws Exception {
- when(brokerFacade.readConfigurationData(any(DOMMountPoint.class), any(YangInstanceIdentifier.class),
- isNull())).thenReturn(prepareCnDataForMountPointTest(false));
- when(mountInstance.getService(DOMSchemaService.class))
- .thenReturn(Optional.of(FixedDOMSchemaService.of(schemaContextTestModule)));
-
- String uri = "/config/ietf-interfaces:interfaces/interface/0/yang-ext:mount/test-module:cont/cont1";
- assertEquals(200, get(uri, MediaType.APPLICATION_XML));
-
- uri = "/config/ietf-interfaces:interfaces/yang-ext:mount/test-module:cont/cont1";
- assertEquals(200, get(uri, MediaType.APPLICATION_XML));
- }
-
- /**
- * MountPoint test. URI represents mount point.
- * Slashes in URI behind mount point. lst1 element with key GigabitEthernet0%2F0%2F0%2F0 (GigabitEthernet0/0/0/0) is
- * requested via GET HTTP operation. It is tested whether %2F character is replaced with simple / in
- * InstanceIdentifier parameter in method
- * {@link BrokerFacade#readConfigurationData(DOMMountPoint, YangInstanceIdentifier)} which is called in
- * method {@link RestconfImpl#readConfigurationData}
- */
- @Test
- public void getDataWithSlashesBehindMountPoint() throws Exception {
- final YangInstanceIdentifier awaitedInstanceIdentifier = prepareInstanceIdentifierForList();
- when(brokerFacade.readConfigurationData(any(DOMMountPoint.class), eq(awaitedInstanceIdentifier),
- isNull())).thenReturn(prepareCnDataForSlashesBehindMountPointTest());
- when(mountInstance.getService(DOMSchemaService.class))
- .thenReturn(Optional.of(FixedDOMSchemaService.of(schemaContextTestModule)));
-
- final String uri = "/config/ietf-interfaces:interfaces/interface/0/yang-ext:mount/"
- + "test-module:cont/lst1/GigabitEthernet0%2F0%2F0%2F0";
- assertEquals(200, get(uri, MediaType.APPLICATION_XML));
- }
-
- private static YangInstanceIdentifier prepareInstanceIdentifierForList() throws Exception {
- final List<PathArgument> parameters = new ArrayList<>();
-
- final QName qNameCont = newTestModuleQName("cont");
- final QName qNameList = newTestModuleQName("lst1");
- final QName qNameKeyList = newTestModuleQName("lf11");
-
- parameters.add(new NodeIdentifier(qNameCont));
- parameters.add(new NodeIdentifier(qNameList));
- parameters.add(NodeIdentifierWithPredicates.of(qNameList, qNameKeyList, "GigabitEthernet0/0/0/0"));
- return YangInstanceIdentifier.create(parameters);
- }
-
- private static QName newTestModuleQName(final String localPart) throws Exception {
- return QName.create("test:module", "2014-01-09", localPart);
- }
-
- @Test
- public void getDataMountPointIntoHighestElement() throws Exception {
- when(brokerFacade.readConfigurationData(any(DOMMountPoint.class), any(YangInstanceIdentifier.class),
- isNull())).thenReturn(prepareCnDataForMountPointTest(true));
- when(mountInstance.getService(DOMSchemaService.class))
- .thenReturn(Optional.of(FixedDOMSchemaService.of(schemaContextTestModule)));
-
- final String uri = "/config/ietf-interfaces:interfaces/interface/0/yang-ext:mount/test-module:cont";
- assertEquals(200, get(uri, MediaType.APPLICATION_XML));
- }
-
- @Test
- public void getDataWithIdentityrefInURL() throws Exception {
- setControllerContext(schemaContextTestModule);
-
- final QName moduleQN = newTestModuleQName("module");
- final ImmutableMap<QName, Object> keyMap = ImmutableMap.of(
- newTestModuleQName("type"), newTestModuleQName("test-identity"),
- newTestModuleQName("name"), "foo");
- final YangInstanceIdentifier iid = YangInstanceIdentifier.builder().node(newTestModuleQName("modules"))
- .node(moduleQN).nodeWithKey(moduleQN, keyMap).build();
- final NormalizedNode data = ImmutableMapNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(moduleQN))
- .withChild(ImmutableNodes.mapEntryBuilder()
- .withNodeIdentifier(NodeIdentifierWithPredicates.of(moduleQN, keyMap))
- .withChild(ImmutableNodes.leafNode(newTestModuleQName("type"), newTestModuleQName("test-identity")))
- .withChild(ImmutableNodes.leafNode(newTestModuleQName("name"), "foo"))
- .withChild(ImmutableNodes.leafNode(newTestModuleQName("data"), "bar")).build()).build();
- when(brokerFacade.readConfigurationData(iid, null)).thenReturn(data);
-
- final String uri = "/config/test-module:modules/module/test-module:test-identity/foo";
- assertEquals(200, get(uri, MediaType.APPLICATION_XML));
- }
-
- // /modules
- @Test
- public void getModulesTest() throws Exception {
- setControllerContext(schemaContextModules);
-
- final String uri = "/modules";
-
- Response response = target(uri).request("application/yang.api+json").get();
- validateModulesResponseJson(response);
-
- response = target(uri).request("application/yang.api+xml").get();
- validateModulesResponseXml(response,schemaContextModules);
- }
-
- // /streams/
- @Test
- @Ignore // FIXME : find why it is fail by in gerrit build
- public void getStreamsTest() throws Exception {
- setControllerContext(schemaContextModules);
-
- final String uri = "/streams";
-
- Response response = target(uri).request("application/yang.api+json").get();
- final String responseBody = response.readEntity(String.class);
- assertEquals(200, response.getStatus());
- assertNotNull(responseBody);
- assertTrue(responseBody.contains("streams"));
-
- response = target(uri).request("application/yang.api+xml").get();
- assertEquals(200, response.getStatus());
- final Document responseXmlBody = response.readEntity(Document.class);
- assertNotNull(responseXmlBody);
- final Element rootNode = responseXmlBody.getDocumentElement();
-
- assertEquals("streams", rootNode.getLocalName());
- assertEquals(RESTCONF_NS, rootNode.getNamespaceURI());
- }
-
- // /modules/module
- @Test
- public void getModuleTest() throws Exception {
- setControllerContext(schemaContextModules);
-
- final String uri = "/modules/module/module2/2014-01-02";
-
- Response response = target(uri).request("application/yang.api+xml").get();
- assertEquals(200, response.getStatus());
- final Document responseXml = response.readEntity(Document.class);
-
- final QName qname = assertedModuleXmlToModuleQName(responseXml.getDocumentElement());
- assertNotNull(qname);
-
- assertEquals("module2", qname.getLocalName());
- assertEquals("module:2", qname.getNamespace().toString());
- assertEquals("2014-01-02", qname.getRevision().get().toString());
-
- response = target(uri).request("application/yang.api+json").get();
- assertEquals(200, response.getStatus());
- final String responseBody = response.readEntity(String.class);
- assertTrue("Module2 in json wasn't found", prepareJsonRegex("module2", "2014-01-02", "module:2", responseBody)
- .find());
- final String[] split = responseBody.split("\"module\"");
- assertEquals("\"module\" element is returned more then once", 2, split.length);
-
- }
-
- // /operations
- @Ignore
- @Test
- public void getOperationsTest() throws Exception {
- setControllerContext(schemaContextModules);
-
- final String uri = "/operations";
-
- Response response = target(uri).request("application/yang.api+xml").get();
- assertEquals(500, response.getStatus());
- final Document responseDoc = response.readEntity(Document.class);
- validateOperationsResponseXml(responseDoc, schemaContextModules);
-
- response = target(uri).request("application/yang.api+json").get();
- assertEquals(200, response.getStatus());
- final String responseBody = response.readEntity(String.class);
- assertTrue("Json response for /operations dummy-rpc1-module1 is incorrect",
- validateOperationsResponseJson(responseBody, "dummy-rpc1-module1", "module1").find());
- assertTrue("Json response for /operations dummy-rpc2-module1 is incorrect",
- validateOperationsResponseJson(responseBody, "dummy-rpc2-module1", "module1").find());
- assertTrue("Json response for /operations dummy-rpc1-module2 is incorrect",
- validateOperationsResponseJson(responseBody, "dummy-rpc1-module2", "module2").find());
- assertTrue("Json response for /operations dummy-rpc2-module2 is incorrect",
- validateOperationsResponseJson(responseBody, "dummy-rpc2-module2", "module2").find());
- }
-
- private static void validateOperationsResponseXml(final Document responseDoc, final SchemaContext schemaContext) {
-
- final Element operationsElem = responseDoc.getDocumentElement();
- assertEquals(RESTCONF_NS, operationsElem.getNamespaceURI());
- assertEquals("operations", operationsElem.getLocalName());
-
- final NodeList operationsList = operationsElem.getChildNodes();
- final HashSet<String> foundOperations = new HashSet<>();
-
- for (int i = 0; i < operationsList.getLength(); i++) {
- final org.w3c.dom.Node operation = operationsList.item(i);
- foundOperations.add(operation.getLocalName());
- }
-
- for (final RpcDefinition schemaOp : schemaContext.getOperations()) {
- assertTrue(foundOperations.contains(schemaOp.getQName().getLocalName()));
- }
- }
-
- // /operations/pathToMountPoint/yang-ext:mount
- @Ignore
- @Test
- public void getOperationsBehindMountPointTest() throws Exception {
- setControllerContext(schemaContextModules);
-
- mockMountPoint();
-
- final String uri = "/operations/ietf-interfaces:interfaces/interface/0/yang-ext:mount/";
-
- Response response = target(uri).request("application/yang.api+xml").get();
- assertEquals(500, response.getStatus());
-
- final Document responseDoc = response.readEntity(Document.class);
- validateOperationsResponseXml(responseDoc, schemaContextBehindMountPoint);
-
- response = target(uri).request("application/yang.api+json").get();
- assertEquals(200, response.getStatus());
- final String responseBody = response.readEntity(String.class);
- assertTrue("Json response for /operations/mount_point rpc-behind-module1 is incorrect",
- validateOperationsResponseJson(responseBody, "rpc-behind-module1", "module1-behind-mount-point").find());
- assertTrue("Json response for /operations/mount_point rpc-behind-module2 is incorrect",
- validateOperationsResponseJson(responseBody, "rpc-behind-module2", "module2-behind-mount-point").find());
-
- }
-
- private static Matcher validateOperationsResponseJson(final String searchIn, final String rpcName,
- final String moduleName) {
- final StringBuilder regex = new StringBuilder();
- regex.append(".*\"" + rpcName + "\"");
- final Pattern ptrn = Pattern.compile(regex.toString(), Pattern.DOTALL);
- return ptrn.matcher(searchIn);
-
- }
-
- // /restconf/modules/pathToMountPoint/yang-ext:mount
- @Test
- public void getModulesBehindMountPoint() throws Exception {
- setControllerContext(schemaContextModules);
-
- mockMountPoint();
-
- final String uri = "/modules/ietf-interfaces:interfaces/interface/0/yang-ext:mount/";
-
- Response response = target(uri).request("application/yang.api+json").get();
- assertEquals(200, response.getStatus());
- final String responseBody = response.readEntity(String.class);
-
- assertTrue(
- "module1-behind-mount-point in json wasn't found",
- prepareJsonRegex("module1-behind-mount-point", "2014-02-03", "module:1:behind:mount:point",
- responseBody).find());
- assertTrue(
- "module2-behind-mount-point in json wasn't found",
- prepareJsonRegex("module2-behind-mount-point", "2014-02-04", "module:2:behind:mount:point",
- responseBody).find());
-
- response = target(uri).request("application/yang.api+xml").get();
- assertEquals(200, response.getStatus());
- validateModulesResponseXml(response, schemaContextBehindMountPoint);
-
- }
-
- // /restconf/modules/module/pathToMountPoint/yang-ext:mount/moduleName/revision
- @Test
- public void getModuleBehindMountPoint() throws Exception {
- setControllerContext(schemaContextModules);
-
- mockMountPoint();
-
- final String uri = "/modules/module/ietf-interfaces:interfaces/interface/0/yang-ext:mount/"
- + "module1-behind-mount-point/2014-02-03";
-
- Response response = target(uri).request("application/yang.api+json").get();
- assertEquals(200, response.getStatus());
- final String responseBody = response.readEntity(String.class);
-
- assertTrue(
- "module1-behind-mount-point in json wasn't found",
- prepareJsonRegex("module1-behind-mount-point", "2014-02-03", "module:1:behind:mount:point",
- responseBody).find());
- final String[] split = responseBody.split("\"module\"");
- assertEquals("\"module\" element is returned more then once", 2, split.length);
-
- response = target(uri).request("application/yang.api+xml").get();
- assertEquals(200, response.getStatus());
- final Document responseXml = response.readEntity(Document.class);
-
- final QName module = assertedModuleXmlToModuleQName(responseXml.getDocumentElement());
-
- assertEquals("module1-behind-mount-point", module.getLocalName());
- assertEquals("2014-02-03", module.getRevision().get().toString());
- assertEquals("module:1:behind:mount:point", module.getNamespace().toString());
- }
-
- private static void validateModulesResponseXml(final Response response, final SchemaContext schemaContext) {
- assertEquals(200, response.getStatus());
- final Document responseBody = response.readEntity(Document.class);
- final NodeList moduleNodes = responseBody.getDocumentElement().getElementsByTagNameNS(RESTCONF_NS, "module");
-
- assertTrue(moduleNodes.getLength() > 0);
-
- final HashSet<QName> foundModules = new HashSet<>();
-
- for (int i = 0; i < moduleNodes.getLength(); i++) {
- final org.w3c.dom.Node module = moduleNodes.item(i);
-
- final QName name = assertedModuleXmlToModuleQName(module);
- foundModules.add(name);
- }
-
- assertAllModules(foundModules,schemaContext);
- }
-
- private static void assertAllModules(final Set<QName> foundModules, final SchemaContext schemaContext) {
- for (final Module module : schemaContext.getModules()) {
- final QName current = QName.create(module.getQNameModule(), module.getName());
- assertTrue("Module not found in response.", foundModules.contains(current));
- }
-
- }
-
- private static QName assertedModuleXmlToModuleQName(final org.w3c.dom.Node module) {
- assertEquals("module", module.getLocalName());
- assertEquals(RESTCONF_NS, module.getNamespaceURI());
- String revision = null;
- String namespace = null;
- String name = null;
-
-
- final NodeList childNodes = module.getChildNodes();
-
- for (int i = 0; i < childNodes.getLength(); i++) {
- final org.w3c.dom.Node child = childNodes.item(i);
- assertEquals(RESTCONF_NS, child.getNamespaceURI());
-
- switch (child.getLocalName()) {
- case "name":
- assertNull("Name element appeared multiple times", name);
- name = child.getTextContent().trim();
- break;
- case "revision":
- assertNull("Revision element appeared multiple times", revision);
- revision = child.getTextContent().trim();
- break;
- case "namespace":
- assertNull("Namespace element appeared multiple times", namespace);
- namespace = child.getTextContent().trim();
- break;
- default:
- break;
- }
- }
-
- assertNotNull("Revision was not part of xml",revision);
- assertNotNull("Module namespace was not part of xml",namespace);
- assertNotNull("Module identiffier was not part of xml",name);
-
- return QName.create(namespace,revision,name);
- }
-
- private static void validateModulesResponseJson(final Response response) {
- assertEquals(200, response.getStatus());
- final String responseBody = response.readEntity(String.class);
-
- assertTrue("Module1 in json wasn't found", prepareJsonRegex("module1", "2014-01-01", "module:1", responseBody)
- .find());
- assertTrue("Module2 in json wasn't found", prepareJsonRegex("module2", "2014-01-02", "module:2", responseBody)
- .find());
- assertTrue("Module3 in json wasn't found", prepareJsonRegex("module3", "2014-01-03", "module:3", responseBody)
- .find());
- }
-
- private static Matcher prepareJsonRegex(final String module, final String revision, final String namespace,
- final String searchIn) {
- final StringBuilder regex = new StringBuilder();
- regex.append("^");
-
- regex.append(".*\\{");
- regex.append(".*\"name\"");
- regex.append(".*:");
- regex.append(".*\"" + module + "\",");
-
- regex.append(".*\"revision\"");
- regex.append(".*:");
- regex.append(".*\"" + revision + "\",");
-
- regex.append(".*\"namespace\"");
- regex.append(".*:");
- regex.append(".*\"" + namespace + "\"");
-
- regex.append(".*\\}");
-
- regex.append(".*");
- regex.append("$");
- final Pattern ptrn = Pattern.compile(regex.toString(), Pattern.DOTALL);
- return ptrn.matcher(searchIn);
-
- }
-
-
- private int get(final String uri, final String mediaType) {
- return target(uri).request(mediaType).get().getStatus();
- }
-
- /**
- * Container structure.
- *
- * <p>
- * container cont {
- * container cont1 {
- * leaf lf11 {
- * type string;
- * }
- */
- private static NormalizedNode prepareCnDataForMountPointTest(final boolean wrapToCont) throws Exception {
- final String testModuleDate = "2014-01-09";
- final ContainerNode contChild = Builders
- .containerBuilder()
- .withNodeIdentifier(TestUtils.getNodeIdentifier("cont1", "test:module", testModuleDate))
- .withChild(
- Builders.leafBuilder()
- .withNodeIdentifier(TestUtils.getNodeIdentifier("lf11", "test:module", testModuleDate))
- .withValue("lf11 value").build()).build();
-
- if (wrapToCont) {
- return Builders.containerBuilder()
- .withNodeIdentifier(TestUtils.getNodeIdentifier("cont", "test:module", testModuleDate))
- .withChild(contChild).build();
- }
- return contChild;
-
- }
-
- private void mockReadOperationalDataMethod() {
- when(brokerFacade.readOperationalData(any(YangInstanceIdentifier.class))).thenReturn(answerFromGet);
- }
-
- private void mockReadConfigurationDataMethod() {
- when(brokerFacade.readConfigurationData(any(YangInstanceIdentifier.class), isNull()))
- .thenReturn(answerFromGet);
- }
-
- private static NormalizedNode prepareCnDataForSlashesBehindMountPointTest() throws Exception {
- return ImmutableMapEntryNodeBuilder.create()
- .withNodeIdentifier(
- TestUtils.getNodeIdentifierPredicate("lst1", "test:module", "2014-01-09", "lf11",
- "GigabitEthernet0/0/0/0"))
- .withChild(
- ImmutableLeafNodeBuilder.create()
- .withNodeIdentifier(TestUtils.getNodeIdentifier("lf11", "test:module", "2014-01-09"))
- .withValue("GigabitEthernet0/0/0/0").build()).build();
-
- }
-
- /**
- * If includeWhiteChars URI parameter is set to false then no white characters can be included in returned output.
- */
- @Test
- public void getDataWithUriIncludeWhiteCharsParameterTest() throws Exception {
- getDataWithUriIncludeWhiteCharsParameter("config");
- getDataWithUriIncludeWhiteCharsParameter("operational");
- }
-
- private void getDataWithUriIncludeWhiteCharsParameter(final String target) throws Exception {
- mockReadConfigurationDataMethod();
- mockReadOperationalDataMethod();
- final String uri = "/" + target + "/ietf-interfaces:interfaces/interface/eth0";
- Response response = target(uri).queryParam("prettyPrint", "false").request("application/xml").get();
- final String xmlData = response.readEntity(String.class);
-
- Pattern pattern = Pattern.compile(".*(>\\s+|\\s+<).*", Pattern.DOTALL);
- Matcher matcher = pattern.matcher(xmlData);
- // XML element can't surrounded with white character (e.g "> " or
- // " <")
- assertFalse(matcher.matches());
-
- response = target(uri).queryParam("prettyPrint", "false").request("application/json").get();
- final String jsonData = response.readEntity(String.class);
- pattern = Pattern.compile(".*(\\}\\s+|\\s+\\{|\\]\\s+|\\s+\\[|\\s+:|:\\s+).*", Pattern.DOTALL);
- matcher = pattern.matcher(jsonData);
- // JSON element can't surrounded with white character (e.g "} ", " {",
- // "] ", " [", " :" or ": ")
- assertFalse(matcher.matches());
- }
-
- /**
- * Tests behavior when invalid value of depth URI parameter.
- */
- @Test
- @Ignore
- public void getDataWithInvalidDepthParameterTest() {
- setControllerContext(schemaContextModules);
-
- final MultivaluedMap<String, String> paramMap = new MultivaluedHashMap<>();
- paramMap.putSingle("depth", "1o");
- final UriInfo mockInfo = mock(UriInfo.class);
- when(mockInfo.getQueryParameters(false)).thenAnswer(invocation -> paramMap);
-
- getDataWithInvalidDepthParameterTest(mockInfo);
-
- paramMap.putSingle("depth", "0");
- getDataWithInvalidDepthParameterTest(mockInfo);
-
- paramMap.putSingle("depth", "-1");
- getDataWithInvalidDepthParameterTest(mockInfo);
- }
-
- private void getDataWithInvalidDepthParameterTest(final UriInfo uriInfo) {
- try {
- final QName qNameDepth1Cont = QName.create("urn:nested:module", "2014-06-3", "depth1-cont");
- final YangInstanceIdentifier ii = YangInstanceIdentifier.builder().node(qNameDepth1Cont).build();
- final NormalizedNode value =
- Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(qNameDepth1Cont)).build();
- when(brokerFacade.readConfigurationData(eq(ii))).thenReturn(value);
- restconfImpl.readConfigurationData("nested-module:depth1-cont", uriInfo);
- fail("Expected RestconfDocumentedException");
- } catch (final RestconfDocumentedException e) {
- assertTrue("Unexpected error message: " + e.getErrors().get(0).getErrorMessage(), e.getErrors().get(0)
- .getErrorMessage().contains("depth"));
- }
- }
-
- @SuppressWarnings("unused")
- private void verifyXMLResponse(final Response response, final NodeData nodeData) {
- final Document doc = response.readEntity(Document.class);
- assertNotNull("Could not parse XML document", doc);
-
- verifyContainerElement(doc.getDocumentElement(), nodeData);
- }
-
- @SuppressWarnings("unchecked")
- private void verifyContainerElement(final Element element, final NodeData nodeData) {
-
- assertEquals("Element local name", nodeData.key, element.getLocalName());
-
- final NodeList childNodes = element.getChildNodes();
- if (nodeData.data == null) { // empty container
- assertTrue(
- "Expected no child elements for \"" + element.getLocalName() + "\"", childNodes.getLength() == 0);
- return;
- }
-
- final Map<String, NodeData> expChildMap = new HashMap<>();
- for (final NodeData expChild : (List<NodeData>) nodeData.data) {
- expChildMap.put(expChild.key.toString(), expChild);
- }
-
- for (int i = 0; i < childNodes.getLength(); i++) {
- final org.w3c.dom.Node actualChild = childNodes.item(i);
- if (!(actualChild instanceof Element)) {
- continue;
- }
-
- final Element actualElement = (Element) actualChild;
- final NodeData expChild = expChildMap.remove(actualElement.getLocalName());
- assertNotNull(
- "Unexpected child element for parent \"" + element.getLocalName() + "\": "
- + actualElement.getLocalName(), expChild);
-
- if (expChild.data == null || expChild.data instanceof List) {
- verifyContainerElement(actualElement, expChild);
- } else {
- assertEquals("Text content for element: " + actualElement.getLocalName(), expChild.data,
- actualElement.getTextContent());
- }
- }
-
- if (!expChildMap.isEmpty()) {
- fail("Missing elements for parent \"" + element.getLocalName() + "\": " + expChildMap.keySet());
- }
- }
-
- private void mockMountPoint() {
- when(mountInstance.getService(DOMSchemaService.class))
- .thenReturn(Optional.of(FixedDOMSchemaService.of(schemaContextBehindMountPoint)));
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-public final class RestOperationUtils {
-
- public static final String JSON = "+json";
- public static final String XML = "+xml";
-
- private RestOperationUtils() {
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.util.concurrent.FluentFuture;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URISyntaxException;
-import java.text.ParseException;
-import java.util.Optional;
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.MediaType;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.BeforeClass;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.dom.api.DOMMountPoint;
-import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
-import org.opendaylight.netconf.sal.rest.api.Draft02;
-import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeJsonBodyWriter;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeXmlBodyWriter;
-import org.opendaylight.netconf.sal.rest.impl.RestconfDocumentedExceptionMapper;
-import org.opendaylight.netconf.sal.rest.impl.XmlNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.restconf.impl.BrokerFacade;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.netconf.sal.restconf.impl.RestconfImpl;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-
-public class RestPostOperationTest extends JerseyTest {
-
- private static String xmlBlockData;
- private static String xmlData3;
- private static String xmlData4;
-
- private static EffectiveModelContext schemaContextYangsIetf;
- private static EffectiveModelContext schemaContextTestModule;
- private static EffectiveModelContext schemaContext;
-
- private BrokerFacade brokerFacade;
- private RestconfImpl restconfImpl;
- private ControllerContext controllerContext;
- private DOMMountPoint mountInstance;
-
- @BeforeClass
- public static void init() throws URISyntaxException, IOException {
- schemaContextYangsIetf = TestUtils.loadSchemaContext("/full-versions/yangs");
- schemaContextTestModule = TestUtils.loadSchemaContext("/full-versions/test-module");
- schemaContext = TestUtils.loadSchemaContext("/test-config-data/yang1");
- loadData();
- }
-
- @Override
- protected Application configure() {
- /* enable/disable Jersey logs to console */
- // enable(TestProperties.LOG_TRAFFIC);
- // enable(TestProperties.DUMP_ENTITY);
- // enable(TestProperties.RECORD_LOG_LEVEL);
- // set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
-
- mountInstance = mock(DOMMountPoint.class);
- controllerContext = TestRestconfUtils.newControllerContext(schemaContext, mountInstance);
- brokerFacade = mock(BrokerFacade.class);
- restconfImpl = RestconfImpl.newInstance(brokerFacade, controllerContext);
-
- ResourceConfig resourceConfig = new ResourceConfig();
- resourceConfig = resourceConfig.registerInstances(restconfImpl,
- new XmlNormalizedNodeBodyReader(controllerContext), new NormalizedNodeXmlBodyWriter(),
- new JsonNormalizedNodeBodyReader(controllerContext), new NormalizedNodeJsonBodyWriter(),
- new RestconfDocumentedExceptionMapper(controllerContext));
- return resourceConfig;
- }
-
- private void setSchemaControllerContext(final EffectiveModelContext schema) {
- controllerContext.setSchemas(schema);
- }
-
- @SuppressWarnings("unchecked")
- @Test
- @Ignore /// xmlData* need netconf-yang
- public void postDataViaUrlMountPoint() throws UnsupportedEncodingException {
- setSchemaControllerContext(schemaContextYangsIetf);
- when(brokerFacade.commitConfigurationDataPost(any(DOMMountPoint.class), any(YangInstanceIdentifier.class),
- any(NormalizedNode.class), null, null)).thenReturn(mock(FluentFuture.class));
-
- when(mountInstance.getService(DOMSchemaService.class))
- .thenReturn(Optional.of(FixedDOMSchemaService.of(schemaContextTestModule)));
-
- String uri = "/config/ietf-interfaces:interfaces/interface/0/";
- assertEquals(204, post(uri, Draft02.MediaTypes.DATA + XML, xmlData4));
- uri = "/config/ietf-interfaces:interfaces/interface/0/yang-ext:mount/test-module:cont";
- assertEquals(204, post(uri, Draft02.MediaTypes.DATA + XML, xmlData3));
-
- assertEquals(400, post(uri, MediaType.APPLICATION_JSON, ""));
- }
-
- @SuppressWarnings("unchecked")
- @Test
- @Ignore //jenkins has problem with JerseyTest
- // - we expecting problems with singletons ControllerContext as schemaContext holder
- public void createConfigurationDataTest() throws UnsupportedEncodingException, ParseException {
- when(brokerFacade.commitConfigurationDataPost((EffectiveModelContext) null, any(YangInstanceIdentifier.class),
- any(NormalizedNode.class), null, null))
- .thenReturn(mock(FluentFuture.class));
-
- final ArgumentCaptor<YangInstanceIdentifier> instanceIdCaptor =
- ArgumentCaptor.forClass(YangInstanceIdentifier.class);
- final ArgumentCaptor<NormalizedNode> compNodeCaptor = ArgumentCaptor.forClass(NormalizedNode.class);
-
-
- // FIXME : identify who is set the schemaContext
-// final String URI_1 = "/config";
-// assertEquals(204, post(URI_1, Draft02.MediaTypes.DATA + XML, xmlTestInterface));
-// verify(brokerFacade).commitConfigurationDataPost(instanceIdCaptor.capture(), compNodeCaptor.capture());
- final String identifier = "[(urn:ietf:params:xml:ns:yang:test-interface?revision=2014-07-01)interfaces]";
-// assertEquals(identifier, ImmutableList.copyOf(instanceIdCaptor.getValue().getPathArguments()).toString());
-
- final String URI_2 = "/config/test-interface:interfaces";
- assertEquals(204, post(URI_2, Draft02.MediaTypes.DATA + XML, xmlBlockData));
- // FIXME : NEVER test a nr. of call some service in complex test suite
-// verify(brokerFacade, times(2))
- verify(brokerFacade, times(1))
- .commitConfigurationDataPost((EffectiveModelContext) null, instanceIdCaptor.capture(),
- compNodeCaptor.capture(), null, null);
-// identifier = "[(urn:ietf:params:xml:ns:yang:test-interface?revision=2014-07-01)interfaces," +
-// "(urn:ietf:params:xml:ns:yang:test-interface?revision=2014-07-01)block]";
- assertEquals(identifier, ImmutableList.copyOf(instanceIdCaptor.getValue().getPathArguments()).toString());
- }
-
- @Test
- public void createConfigurationDataNullTest() throws UnsupportedEncodingException {
- doReturn(CommitInfo.emptyFluentFuture()).when(brokerFacade).commitConfigurationDataPost(
- any(EffectiveModelContext.class), any(YangInstanceIdentifier.class), any(NormalizedNode.class), isNull(),
- isNull());
-
- //FIXME : find who is set schemaContext
-// final String URI_1 = "/config";
-// assertEquals(204, post(URI_1, Draft02.MediaTypes.DATA + XML, xmlTestInterface));
-
- final String URI_2 = "/config/test-interface:interfaces";
- assertEquals(204, post(URI_2, Draft02.MediaTypes.DATA + XML, xmlBlockData));
- }
-
- private int post(final String uri, final String mediaType, final String data) {
- return target(uri).request(mediaType).post(Entity.entity(data, mediaType)).getStatus();
- }
-
- private static void loadData() throws IOException, URISyntaxException {
- final String xmlPathBlockData =
- RestconfImplTest.class.getResource("/test-config-data/xml/block-data.xml").getPath();
- xmlBlockData = TestUtils.loadTextFile(xmlPathBlockData);
- final String data3Input = RestconfImplTest.class.getResource("/full-versions/test-data2/data3.xml").getPath();
- xmlData3 = TestUtils.loadTextFile(data3Input);
- final String data4Input = RestconfImplTest.class.getResource("/full-versions/test-data2/data7.xml").getPath();
- xmlData4 = TestUtils.loadTextFile(data4Input);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.controller.sal.restconf.impl.test;
-
-import java.io.FileNotFoundException;
-import java.util.HashSet;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response.Status;
-import javax.ws.rs.core.UriInfo;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.junit.MockitoJUnitRunner;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.restconf.impl.BrokerFacade;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.netconf.sal.restconf.impl.PutResult;
-import org.opendaylight.netconf.sal.restconf.impl.RestconfImpl;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-
-@RunWith(MockitoJUnitRunner.class)
-public class RestPutConfigTest {
-
- private static EffectiveModelContext schemaContext;
- private RestconfImpl restconfService;
- private ControllerContext controllerCx;
-
- @Mock
- private BrokerFacade brokerFacade;
-
- @BeforeClass
- public static void staticInit() throws FileNotFoundException {
- schemaContext = TestRestconfUtils.loadSchemaContext("/test-config-data/yang1/", null);
- }
-
- @Before
- public void init() {
- controllerCx = TestRestconfUtils.newControllerContext(schemaContext);
- restconfService = RestconfImpl.newInstance(brokerFacade, controllerCx);
- }
-
- @Test
- public void testPutConfigData() {
- final String identifier = "test-interface:interfaces/interface/key";
- final InstanceIdentifierContext iiCx = controllerCx.toInstanceIdentifier(identifier);
- final MapEntryNode data = Mockito.mock(MapEntryNode.class);
- final QName qName = QName.create("urn:ietf:params:xml:ns:yang:test-interface", "2014-07-01", "interface");
- final QName qNameKey = QName.create("urn:ietf:params:xml:ns:yang:test-interface", "2014-07-01", "name");
- final NodeIdentifierWithPredicates identWithPredicates =
- NodeIdentifierWithPredicates.of(qName, qNameKey, "key");
- Mockito.when(data.getIdentifier()).thenReturn(identWithPredicates);
- final NormalizedNodeContext payload = new NormalizedNodeContext(iiCx, data);
-
- mockingBrokerPut(iiCx.getInstanceIdentifier(), data);
-
- final UriInfo uriInfo = Mockito.mock(UriInfo.class);
- final MultivaluedMap<String, String> value = Mockito.mock(MultivaluedMap.class);
- Mockito.when(value.entrySet()).thenReturn(new HashSet<>());
- Mockito.when(uriInfo.getQueryParameters()).thenReturn(value);
- restconfService.updateConfigurationData(identifier, payload, uriInfo);
- }
-
- @Test
- public void testPutConfigDataCheckOnlyLastElement() {
- final String identifier = "test-interface:interfaces/interface/key/sub-interface/subkey";
- final InstanceIdentifierContext iiCx = controllerCx.toInstanceIdentifier(identifier);
- final MapEntryNode data = Mockito.mock(MapEntryNode.class);
- final QName qName = QName.create("urn:ietf:params:xml:ns:yang:test-interface", "2014-07-01", "sub-interface");
- final QName qNameSubKey = QName.create("urn:ietf:params:xml:ns:yang:test-interface", "2014-07-01", "sub-name");
- final NodeIdentifierWithPredicates identWithPredicates =
- NodeIdentifierWithPredicates.of(qName, qNameSubKey, "subkey");
- Mockito.when(data.getIdentifier()).thenReturn(identWithPredicates);
- final NormalizedNodeContext payload = new NormalizedNodeContext(iiCx, data);
-
- mockingBrokerPut(iiCx.getInstanceIdentifier(), data);
-
- final UriInfo uriInfo = Mockito.mock(UriInfo.class);
- final MultivaluedMap<String, String> value = Mockito.mock(MultivaluedMap.class);
- Mockito.when(value.entrySet()).thenReturn(new HashSet<>());
- Mockito.when(uriInfo.getQueryParameters()).thenReturn(value);
- restconfService.updateConfigurationData(identifier, payload, uriInfo);
- }
-
- @Test(expected = RestconfDocumentedException.class)
- public void testPutConfigDataMissingUriKey() {
- final String identifier = "test-interface:interfaces/interface";
- controllerCx.toInstanceIdentifier(identifier);
- }
-
- @Test(expected = RestconfDocumentedException.class)
- public void testPutConfigDataDiferentKey() {
- final String identifier = "test-interface:interfaces/interface/key";
- final InstanceIdentifierContext iiCx = controllerCx.toInstanceIdentifier(identifier);
- final MapEntryNode data = Mockito.mock(MapEntryNode.class);
- final QName qName = QName.create("urn:ietf:params:xml:ns:yang:test-interface", "2014-07-01", "interface");
- final QName qNameKey = QName.create("urn:ietf:params:xml:ns:yang:test-interface", "2014-07-01", "name");
- final NodeIdentifierWithPredicates identWithPredicates =
- NodeIdentifierWithPredicates.of(qName, qNameKey, "notSameKey");
- Mockito.when(data.getIdentifier()).thenReturn(identWithPredicates);
- final NormalizedNodeContext payload = new NormalizedNodeContext(iiCx, data);
-
- mockingBrokerPut(iiCx.getInstanceIdentifier(), data);
-
- final UriInfo uriInfo = Mockito.mock(UriInfo.class);
- final MultivaluedMap<String, String> value = Mockito.mock(MultivaluedMap.class);
- Mockito.when(value.entrySet()).thenReturn(new HashSet<>());
- Mockito.when(uriInfo.getQueryParameters()).thenReturn(value);
- restconfService.updateConfigurationData(identifier, payload, uriInfo);
- }
-
- private void mockingBrokerPut(final YangInstanceIdentifier yii, final NormalizedNode data) {
- final PutResult result = Mockito.mock(PutResult.class);
- Mockito.when(brokerFacade.commitConfigurationDataPut(schemaContext, yii, data, null, null))
- .thenReturn(result);
- Mockito.doReturn(CommitInfo.emptyFluentFuture()).when(result).getFutureOfPutData();
- Mockito.when(result.getStatus()).thenReturn(Status.OK);
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URISyntaxException;
-import java.util.Optional;
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.BeforeClass;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.common.api.OptimisticLockFailedException;
-import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
-import org.opendaylight.mdsal.dom.api.DOMMountPoint;
-import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
-import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeJsonBodyWriter;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeXmlBodyWriter;
-import org.opendaylight.netconf.sal.rest.impl.RestconfDocumentedExceptionMapper;
-import org.opendaylight.netconf.sal.rest.impl.XmlNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.restconf.impl.BrokerFacade;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.netconf.sal.restconf.impl.PutResult;
-import org.opendaylight.netconf.sal.restconf.impl.RestconfImpl;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
-
-//TODO UNSTABLE TESTS - FIX ME
-@Ignore
-public class RestPutOperationTest extends JerseyTest {
-
- private static String xmlData;
- private static String xmlData2;
- private static String xmlData3;
-
- private static EffectiveModelContext schemaContextYangsIetf;
- private static EffectiveModelContext schemaContextTestModule;
-
- private BrokerFacade brokerFacade;
- private RestconfImpl restconfImpl;
- private DOMMountPoint mountInstance;
-
- @BeforeClass
- public static void init() throws IOException, ReactorException {
- schemaContextYangsIetf = TestUtils.loadSchemaContext("/full-versions/yangs");
- schemaContextTestModule = TestUtils.loadSchemaContext("/full-versions/test-module");
- loadData();
- }
-
- private static void loadData() throws IOException {
- final InputStream xmlStream =
- RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
- xmlData = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
- final InputStream xmlStream2 =
- RestconfImplTest.class.getResourceAsStream("/full-versions/test-data2/data2.xml");
- xmlData2 = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream2));
- final InputStream xmlStream3 =
- RestconfImplTest.class.getResourceAsStream("/full-versions/test-data2/data7.xml");
- xmlData3 = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream3));
- }
-
- @Override
- protected Application configure() {
- /* enable/disable Jersey logs to console */
- // enable(TestProperties.LOG_TRAFFIC);
- // enable(TestProperties.DUMP_ENTITY);
- // enable(TestProperties.RECORD_LOG_LEVEL);
- // set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
-
- mountInstance = mock(DOMMountPoint.class);
- final ControllerContext controllerContext =
- TestRestconfUtils.newControllerContext(schemaContextYangsIetf, mountInstance);
- brokerFacade = mock(BrokerFacade.class);
- restconfImpl = RestconfImpl.newInstance(brokerFacade, controllerContext);
-
- ResourceConfig resourceConfig = new ResourceConfig();
- resourceConfig = resourceConfig.registerInstances(restconfImpl,
- new XmlNormalizedNodeBodyReader(controllerContext), new NormalizedNodeXmlBodyWriter(),
- new JsonNormalizedNodeBodyReader(controllerContext), new NormalizedNodeJsonBodyWriter(),
- new RestconfDocumentedExceptionMapper(controllerContext));
- return resourceConfig;
- }
-
- /**
- * Tests of status codes for "/config/{identifier}".
- */
- @Test
- public void putConfigStatusCodes() throws UnsupportedEncodingException {
- final String uri = "/config/ietf-interfaces:interfaces/interface/eth0";
- mockCommitConfigurationDataPutMethod(true);
- assertEquals(500, put(uri, MediaType.APPLICATION_XML, xmlData));
-
- mockCommitConfigurationDataPutMethod(false);
- assertEquals(500, put(uri, MediaType.APPLICATION_XML, xmlData));
-
- assertEquals(400, put(uri, MediaType.APPLICATION_JSON, ""));
- }
-
- @Test
- public void putConfigStatusCodesEmptyBody() throws UnsupportedEncodingException {
- final String uri = "/config/ietf-interfaces:interfaces/interface/eth0";
- @SuppressWarnings("unused")
- final Response resp = target(uri).request(MediaType.APPLICATION_JSON).put(
- Entity.entity("", MediaType.APPLICATION_JSON));
- assertEquals(400, put(uri, MediaType.APPLICATION_JSON, ""));
- }
-
- @Test
- public void testRpcResultCommitedToStatusCodesWithMountPoint() throws UnsupportedEncodingException,
- FileNotFoundException, URISyntaxException {
- final PutResult result = mock(PutResult.class);
- when(brokerFacade.commitMountPointDataPut(any(DOMMountPoint.class), any(YangInstanceIdentifier.class),
- any(NormalizedNode.class), null, null)).thenReturn(result);
- doReturn(CommitInfo.emptyFluentFuture()).when(result).getFutureOfPutData();
- when(result.getStatus()).thenReturn(Status.OK);
-
- mockMountPoint();
-
- String uri = "/config/ietf-interfaces:interfaces/interface/0/yang-ext:mount/test-module:cont";
- assertEquals(200, put(uri, MediaType.APPLICATION_XML, xmlData2));
-
- uri = "/config/ietf-interfaces:interfaces/yang-ext:mount/test-module:cont";
- assertEquals(200, put(uri, MediaType.APPLICATION_XML, xmlData2));
- }
-
- @Test
- public void putDataMountPointIntoHighestElement() throws UnsupportedEncodingException, URISyntaxException {
- final PutResult result = mock(PutResult.class);
- doReturn(result).when(brokerFacade).commitMountPointDataPut(any(DOMMountPoint.class),
- any(YangInstanceIdentifier.class), any(NormalizedNode.class), null, null);
- doReturn(CommitInfo.emptyFluentFuture()).when(result).getFutureOfPutData();
- when(result.getStatus()).thenReturn(Status.OK);
-
- mockMountPoint();
-
- final String uri = "/config/ietf-interfaces:interfaces/yang-ext:mount";
- assertEquals(200, put(uri, MediaType.APPLICATION_XML, xmlData3));
- }
-
- @Test
- public void putWithOptimisticLockFailedException() throws UnsupportedEncodingException {
-
- final String uri = "/config/ietf-interfaces:interfaces/interface/eth0";
-
- doThrow(OptimisticLockFailedException.class).when(brokerFacade).commitConfigurationDataPut(
- any(EffectiveModelContext.class), any(YangInstanceIdentifier.class), any(NormalizedNode.class), null,
- null);
-
- assertEquals(500, put(uri, MediaType.APPLICATION_XML, xmlData));
-
- doThrow(OptimisticLockFailedException.class).doReturn(mock(PutResult.class)).when(brokerFacade)
- .commitConfigurationDataPut(any(EffectiveModelContext.class), any(YangInstanceIdentifier.class),
- any(NormalizedNode.class), null, null);
-
- assertEquals(500, put(uri, MediaType.APPLICATION_XML, xmlData));
- }
-
- @Test
- public void putWithTransactionCommitFailedException() throws UnsupportedEncodingException {
-
- final String uri = "/config/ietf-interfaces:interfaces/interface/eth0";
-
- doThrow(TransactionCommitFailedException.class)
- .when(brokerFacade).commitConfigurationDataPut(
- any(EffectiveModelContext.class), any(YangInstanceIdentifier.class), any(NormalizedNode.class),
- null, null);
-
- assertEquals(500, put(uri, MediaType.APPLICATION_XML, xmlData));
- }
-
- private int put(final String uri, final String mediaType, final String data) throws UnsupportedEncodingException {
- return target(uri).request(mediaType).put(Entity.entity(data, mediaType)).getStatus();
- }
-
- private void mockMountPoint() {
- when(mountInstance.getService(DOMSchemaService.class))
- .thenReturn(Optional.of(FixedDOMSchemaService.of(schemaContextTestModule)));
- }
-
- private void mockCommitConfigurationDataPutMethod(final boolean noErrors) {
- final PutResult putResMock = mock(PutResult.class);
- if (noErrors) {
- doReturn(putResMock).when(brokerFacade).commitConfigurationDataPut(
- any(EffectiveModelContext.class), any(YangInstanceIdentifier.class), any(NormalizedNode.class),
- null, null);
- } else {
- doThrow(RestconfDocumentedException.class).when(brokerFacade).commitConfigurationDataPut(
- any(EffectiveModelContext.class), any(YangInstanceIdentifier.class), any(NormalizedNode.class),
- null, null);
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Brocade Communications 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.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.when;
-
-import com.google.common.collect.Iterators;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParser;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
-import javax.ws.rs.core.UriInfo;
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpression;
-import javax.xml.xpath.XPathFactory;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.netconf.sal.rest.api.Draft02;
-import org.opendaylight.netconf.sal.rest.api.RestconfService;
-import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeJsonBodyWriter;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeXmlBodyWriter;
-import org.opendaylight.netconf.sal.rest.impl.RestconfDocumentedExceptionMapper;
-import org.opendaylight.netconf.sal.rest.impl.XmlNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.errors.RestconfError;
-import org.opendaylight.yangtools.util.xml.UntrustedXML;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.common.ErrorType;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-/**
- * Unit tests for RestconfDocumentedExceptionMapper.
- *
- * @author Thomas Pantelis
- */
-public class RestconfDocumentedExceptionMapperTest extends JerseyTest {
-
- interface ErrorInfoVerifier {
- void verifyXML(Node errorInfoNode);
-
- void verifyJson(JsonElement errorInfoElement);
- }
-
- static class SimpleErrorInfoVerifier implements ErrorInfoVerifier {
-
- String expTextContent;
-
- SimpleErrorInfoVerifier(final String expErrorInfo) {
- expTextContent = expErrorInfo;
- }
-
- void verifyContent(final String actualContent) {
- assertNotNull("Actual \"error-info\" text content is null", actualContent);
- assertTrue("", actualContent.contains(expTextContent));
- }
-
- @Override
- public void verifyXML(final Node errorInfoNode) {
- verifyContent(errorInfoNode.getTextContent());
- }
-
- @Override
- public void verifyJson(final JsonElement errorInfoElement) {
- verifyContent(errorInfoElement.getAsString());
- }
- }
-
- private static final Logger LOG = LoggerFactory.getLogger(RestconfDocumentedExceptionMapperTest.class);
- private static final String IETF_RESTCONF = "ietf-restconf";
- static RestconfService mockRestConf = mock(RestconfService.class);
-
- static XPath XPATH = XPathFactory.newInstance().newXPath();
- static XPathExpression ERROR_LIST;
- static XPathExpression ERROR_TYPE;
- static XPathExpression ERROR_TAG;
- static XPathExpression ERROR_MESSAGE;
- static XPathExpression ERROR_APP_TAG;
- static XPathExpression ERROR_INFO;
-
- private static EffectiveModelContext schemaContext;
-
- @BeforeClass
- public static void init() throws Exception {
- schemaContext = TestUtils.loadSchemaContext("/modules");
-
- final NamespaceContext nsContext = new NamespaceContext() {
- @Override
- public Iterator<String> getPrefixes(final String namespaceURI) {
- return Iterators.singletonIterator(IETF_RESTCONF);
- }
-
- @Override
- public String getPrefix(final String namespaceURI) {
- return null;
- }
-
- @Override
- public String getNamespaceURI(final String prefix) {
- return IETF_RESTCONF.equals(prefix) ? Draft02.RestConfModule.NAMESPACE : null;
- }
- };
-
- XPATH.setNamespaceContext(nsContext);
- ERROR_LIST = XPATH.compile("ietf-restconf:errors/ietf-restconf:error");
- ERROR_TYPE = XPATH.compile("ietf-restconf:error-type");
- ERROR_TAG = XPATH.compile("ietf-restconf:error-tag");
- ERROR_MESSAGE = XPATH.compile("ietf-restconf:error-message");
- ERROR_APP_TAG = XPATH.compile("ietf-restconf:error-app-tag");
- ERROR_INFO = XPATH.compile("ietf-restconf:error-info");
- }
-
- @Override
- @Before
- public void setUp() throws Exception {
- reset(mockRestConf);
- super.setUp();
- }
-
- @Override
- protected Application configure() {
- ResourceConfig resourceConfig = new ResourceConfig();
- ControllerContext controllerContext = TestRestconfUtils.newControllerContext(schemaContext);
- resourceConfig = resourceConfig.registerInstances(mockRestConf,
- new XmlNormalizedNodeBodyReader(controllerContext), new JsonNormalizedNodeBodyReader(controllerContext),
- new NormalizedNodeJsonBodyWriter(), new NormalizedNodeXmlBodyWriter(),
- new RestconfDocumentedExceptionMapper(controllerContext));
- return resourceConfig;
- }
-
- void stageMockEx(final RestconfDocumentedException ex) {
- reset(mockRestConf);
- when(mockRestConf.readOperationalData(any(String.class), any(UriInfo.class))).thenThrow(ex);
- }
-
- void testJsonResponse(final RestconfDocumentedException ex, final Status expStatus, final ErrorType expErrorType,
- final ErrorTag expErrorTag, final String expErrorMessage, final String expErrorAppTag,
- final ErrorInfoVerifier errorInfoVerifier) throws Exception {
-
- stageMockEx(ex);
-
- final Response resp = target("/operational/foo").request(MediaType.APPLICATION_JSON).get();
-
- final InputStream stream = verifyResponse(resp, MediaType.APPLICATION_JSON, expStatus);
-
- verifyJsonResponseBody(stream, expErrorType, expErrorTag, expErrorMessage, expErrorAppTag, errorInfoVerifier);
- }
-
- @Test
- public void testToJsonResponseWithMessageOnly() throws Exception {
-
- testJsonResponse(new RestconfDocumentedException("mock error"), Status.INTERNAL_SERVER_ERROR,
- ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, "mock error", null, null);
-
-
- // To test verification code
- // String json =
- // "{ errors: {" +
- // " error: [{" +
- // " error-tag : \"operation-failed\"" +
- // " ,error-type : \"application\"" +
- // " ,error-message : \"An error occurred\"" +
- // " ,error-info : {" +
- // " session-id: \"123\"" +
- // " ,address: \"1.2.3.4\"" +
- // " }" +
- // " }]" +
- // " }" +
- // "}";
- //
- // verifyJsonResponseBody( new java.io.StringBufferInputStream(json ),
- // ErrorType.APPLICATION,
- // ErrorTag.OPERATION_FAILED, "An error occurred", null,
- // com.google.common.collect.ImmutableMap.of( "session-id", "123",
- // "address", "1.2.3.4" ) );
- }
-
- @Test
- public void testToJsonResponseWithInUseErrorTag() throws Exception {
-
- testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.IN_USE),
- Status.CONFLICT, ErrorType.PROTOCOL, ErrorTag.IN_USE, "mock error", null, null);
- }
-
- @Test
- public void testToJsonResponseWithInvalidValueErrorTag() throws Exception {
-
- testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.RPC, ErrorTag.INVALID_VALUE),
- Status.BAD_REQUEST, ErrorType.RPC, ErrorTag.INVALID_VALUE, "mock error", null, null);
-
- }
-
- @Test
- public void testToJsonResponseWithTooBigErrorTag() throws Exception {
-
- testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.TRANSPORT, ErrorTag.TOO_BIG),
- Status.REQUEST_ENTITY_TOO_LARGE, ErrorType.TRANSPORT, ErrorTag.TOO_BIG, "mock error", null, null);
-
- }
-
- @Test
- public void testToJsonResponseWithMissingAttributeErrorTag() throws Exception {
-
- testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.MISSING_ATTRIBUTE),
- Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.MISSING_ATTRIBUTE, "mock error", null, null);
- }
-
- @Test
- public void testToJsonResponseWithBadAttributeErrorTag() throws Exception {
-
- testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.BAD_ATTRIBUTE),
- Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.BAD_ATTRIBUTE, "mock error", null, null);
- }
-
- @Test
- public void testToJsonResponseWithUnknownAttributeErrorTag() throws Exception {
-
- testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ATTRIBUTE),
- Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ATTRIBUTE, "mock error", null, null);
- }
-
- @Test
- public void testToJsonResponseWithBadElementErrorTag() throws Exception {
-
- testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT),
- Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT, "mock error", null, null);
- }
-
- @Test
- public void testToJsonResponseWithUnknownElementErrorTag() throws Exception {
-
- testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT),
- Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT, "mock error", null, null);
- }
-
- @Test
- public void testToJsonResponseWithUnknownNamespaceErrorTag() throws Exception {
-
- testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_NAMESPACE),
- Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.UNKNOWN_NAMESPACE, "mock error", null, null);
- }
-
- @Test
- public void testToJsonResponseWithMalformedMessageErrorTag() throws Exception {
-
- testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE),
- Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE, "mock error", null, null);
- }
-
- @Test
- public void testToJsonResponseWithAccessDeniedErrorTag() throws Exception {
-
- testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.ACCESS_DENIED),
- Status.FORBIDDEN, ErrorType.PROTOCOL, ErrorTag.ACCESS_DENIED, "mock error", null, null);
- }
-
- @Test
- public void testToJsonResponseWithLockDeniedErrorTag() throws Exception {
-
- testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.LOCK_DENIED),
- Status.CONFLICT, ErrorType.PROTOCOL, ErrorTag.LOCK_DENIED, "mock error", null, null);
- }
-
- @Test
- public void testToJsonResponseWithResourceDeniedErrorTag() throws Exception {
-
- testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.RESOURCE_DENIED),
- Status.CONFLICT, ErrorType.PROTOCOL, ErrorTag.RESOURCE_DENIED, "mock error", null, null);
- }
-
- @Test
- public void testToJsonResponseWithRollbackFailedErrorTag() throws Exception {
-
- testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.ROLLBACK_FAILED),
- Status.INTERNAL_SERVER_ERROR, ErrorType.PROTOCOL, ErrorTag.ROLLBACK_FAILED, "mock error", null, null);
- }
-
- @Test
- public void testToJsonResponseWithDataExistsErrorTag() throws Exception {
-
- testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.DATA_EXISTS),
- Status.CONFLICT, ErrorType.PROTOCOL, ErrorTag.DATA_EXISTS, "mock error", null, null);
- }
-
- @Test
- public void testToJsonResponseWithDataMissingErrorTag() throws Exception {
-
- testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.DATA_MISSING),
- Status.CONFLICT, ErrorType.PROTOCOL, ErrorTag.DATA_MISSING, "mock error", null, null);
- }
-
- @Test
- public void testToJsonResponseWithOperationNotSupportedErrorTag() throws Exception {
-
- testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL,
- ErrorTag.OPERATION_NOT_SUPPORTED), Status.NOT_IMPLEMENTED, ErrorType.PROTOCOL,
- ErrorTag.OPERATION_NOT_SUPPORTED, "mock error", null, null);
- }
-
- @Test
- public void testToJsonResponseWithOperationFailedErrorTag() throws Exception {
-
- testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.OPERATION_FAILED),
- Status.INTERNAL_SERVER_ERROR, ErrorType.PROTOCOL, ErrorTag.OPERATION_FAILED, "mock error", null, null);
- }
-
- @Test
- public void testToJsonResponseWithPartialOperationErrorTag() throws Exception {
-
- testJsonResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.PARTIAL_OPERATION),
- Status.INTERNAL_SERVER_ERROR, ErrorType.PROTOCOL, ErrorTag.PARTIAL_OPERATION, "mock error", null, null);
- }
-
- @Test
- public void testToJsonResponseWithErrorAppTag() throws Exception {
-
- testJsonResponse(new RestconfDocumentedException(new RestconfError(ErrorType.APPLICATION,
- ErrorTag.INVALID_VALUE, "mock error", "mock-app-tag")), Status.BAD_REQUEST, ErrorType.APPLICATION,
- ErrorTag.INVALID_VALUE, "mock error", "mock-app-tag", null);
- }
-
- @Test
- @Ignore // FIXME : find why it return "error-type" RPC no expected APPLICATION
- public void testToJsonResponseWithMultipleErrors() throws Exception {
-
- final List<RestconfError> errorList = Arrays.asList(
- new RestconfError(ErrorType.APPLICATION, ErrorTag.LOCK_DENIED, "mock error1"),
- new RestconfError(ErrorType.RPC, ErrorTag.ROLLBACK_FAILED, "mock error2"));
- stageMockEx(new RestconfDocumentedException("mock", null, errorList));
-
- final Response resp = target("/operational/foo").request(MediaType.APPLICATION_JSON).get();
-
- final InputStream stream = verifyResponse(resp, MediaType.APPLICATION_JSON, Status.CONFLICT);
-
- final JsonArray arrayElement = parseJsonErrorArrayElement(stream);
-
- assertEquals("\"error\" Json array element length", 2, arrayElement.size());
-
- verifyJsonErrorNode(
- arrayElement.get(0), ErrorType.APPLICATION, ErrorTag.LOCK_DENIED, "mock error1", null, null);
-
- verifyJsonErrorNode(arrayElement.get(1), ErrorType.RPC, ErrorTag.ROLLBACK_FAILED, "mock error2", null, null);
- }
-
- @Test
- public void testToJsonResponseWithErrorInfo() throws Exception {
-
- final String errorInfo = "<address>1.2.3.4</address> <session-id>123</session-id>";
- testJsonResponse(new RestconfDocumentedException(new RestconfError(ErrorType.APPLICATION,
- ErrorTag.INVALID_VALUE, "mock error", "mock-app-tag", errorInfo)), Status.BAD_REQUEST,
- ErrorType.APPLICATION, ErrorTag.INVALID_VALUE, "mock error", "mock-app-tag",
- new SimpleErrorInfoVerifier(errorInfo));
- }
-
- @Test
- public void testToJsonResponseWithExceptionCause() throws Exception {
-
- final Exception cause = new Exception("mock exception cause");
- testJsonResponse(new RestconfDocumentedException("mock error", cause), Status.INTERNAL_SERVER_ERROR,
- ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, "mock error", null,
- new SimpleErrorInfoVerifier(cause.getMessage()));
- }
-
- void testXMLResponse(final RestconfDocumentedException ex, final Status expStatus, final ErrorType expErrorType,
- final ErrorTag expErrorTag, final String expErrorMessage, final String expErrorAppTag,
- final ErrorInfoVerifier errorInfoVerifier) throws Exception {
- stageMockEx(ex);
-
- final Response resp = target("/operational/foo").request(MediaType.APPLICATION_XML).get();
-
- final InputStream stream = verifyResponse(resp, MediaType.APPLICATION_XML, expStatus);
-
- verifyXMLResponseBody(stream, expErrorType, expErrorTag, expErrorMessage, expErrorAppTag, errorInfoVerifier);
- }
-
- @Test
- public void testToXMLResponseWithMessageOnly() throws Exception {
-
- testXMLResponse(new RestconfDocumentedException("mock error"), Status.INTERNAL_SERVER_ERROR,
- ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, "mock error", null, null);
-
- // To test verification code
- // String xml =
- // "<errors xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf\">"+
- // " <error>" +
- // " <error-type>application</error-type>"+
- // " <error-tag>operation-failed</error-tag>"+
- // " <error-message>An error occurred</error-message>"+
- // " <error-info>" +
- // " <session-id>123</session-id>" +
- // " <address>1.2.3.4</address>" +
- // " </error-info>" +
- // " </error>" +
- // "</errors>";
- //
- // verifyXMLResponseBody( new java.io.StringBufferInputStream(xml),
- // ErrorType.APPLICATION,
- // ErrorTag.OPERATION_FAILED, "An error occurred", null,
- // com.google.common.collect.ImmutableMap.of( "session-id", "123",
- // "address", "1.2.3.4" ) );
- }
-
- @Test
- public void testToXMLResponseWithInUseErrorTag() throws Exception {
-
- testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.IN_USE),
- Status.CONFLICT, ErrorType.PROTOCOL, ErrorTag.IN_USE, "mock error", null, null);
- }
-
- @Test
- public void testToXMLResponseWithInvalidValueErrorTag() throws Exception {
-
- testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.RPC, ErrorTag.INVALID_VALUE),
- Status.BAD_REQUEST, ErrorType.RPC, ErrorTag.INVALID_VALUE, "mock error", null, null);
- }
-
- @Test
- public void testToXMLResponseWithTooBigErrorTag() throws Exception {
-
- testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.TRANSPORT, ErrorTag.TOO_BIG),
- Status.REQUEST_ENTITY_TOO_LARGE, ErrorType.TRANSPORT, ErrorTag.TOO_BIG, "mock error", null, null);
- }
-
- @Test
- public void testToXMLResponseWithMissingAttributeErrorTag() throws Exception {
-
- testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.MISSING_ATTRIBUTE),
- Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.MISSING_ATTRIBUTE, "mock error", null, null);
- }
-
- @Test
- public void testToXMLResponseWithBadAttributeErrorTag() throws Exception {
-
- testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.BAD_ATTRIBUTE),
- Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.BAD_ATTRIBUTE, "mock error", null, null);
- }
-
- @Test
- public void testToXMLResponseWithUnknownAttributeErrorTag() throws Exception {
-
- testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ATTRIBUTE),
- Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ATTRIBUTE, "mock error", null, null);
- }
-
- @Test
- public void testToXMLResponseWithBadElementErrorTag() throws Exception {
-
- testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT),
- Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT, "mock error", null, null);
- }
-
- @Test
- public void testToXMLResponseWithUnknownElementErrorTag() throws Exception {
-
- testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT),
- Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT, "mock error", null, null);
- }
-
- @Test
- public void testToXMLResponseWithUnknownNamespaceErrorTag() throws Exception {
-
- testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_NAMESPACE),
- Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.UNKNOWN_NAMESPACE, "mock error", null, null);
- }
-
- @Test
- public void testToXMLResponseWithMalformedMessageErrorTag() throws Exception {
-
- testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE),
- Status.BAD_REQUEST, ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE, "mock error", null, null);
- }
-
- @Test
- public void testToXMLResponseWithAccessDeniedErrorTag() throws Exception {
-
- testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.ACCESS_DENIED),
- Status.FORBIDDEN, ErrorType.PROTOCOL, ErrorTag.ACCESS_DENIED, "mock error", null, null);
- }
-
- @Test
- public void testToXMLResponseWithLockDeniedErrorTag() throws Exception {
-
- testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.LOCK_DENIED),
- Status.CONFLICT, ErrorType.PROTOCOL, ErrorTag.LOCK_DENIED, "mock error", null, null);
- }
-
- @Test
- public void testToXMLResponseWithResourceDeniedErrorTag() throws Exception {
-
- testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.RESOURCE_DENIED),
- Status.CONFLICT, ErrorType.PROTOCOL, ErrorTag.RESOURCE_DENIED, "mock error", null, null);
- }
-
- @Test
- public void testToXMLResponseWithRollbackFailedErrorTag() throws Exception {
-
- testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.ROLLBACK_FAILED),
- Status.INTERNAL_SERVER_ERROR, ErrorType.PROTOCOL, ErrorTag.ROLLBACK_FAILED, "mock error", null, null);
- }
-
- @Test
- public void testToXMLResponseWithDataExistsErrorTag() throws Exception {
-
- testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.DATA_EXISTS),
- Status.CONFLICT, ErrorType.PROTOCOL, ErrorTag.DATA_EXISTS, "mock error", null, null);
- }
-
- @Test
- public void testToXMLResponseWithDataMissingErrorTag() throws Exception {
-
- testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.DATA_MISSING),
- Status.CONFLICT, ErrorType.PROTOCOL, ErrorTag.DATA_MISSING, "mock error", null, null);
- }
-
- @Test
- public void testToXMLResponseWithOperationNotSupportedErrorTag() throws Exception {
-
- testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL,
- ErrorTag.OPERATION_NOT_SUPPORTED), Status.NOT_IMPLEMENTED, ErrorType.PROTOCOL,
- ErrorTag.OPERATION_NOT_SUPPORTED, "mock error", null, null);
- }
-
- @Test
- public void testToXMLResponseWithOperationFailedErrorTag() throws Exception {
-
- testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.OPERATION_FAILED),
- Status.INTERNAL_SERVER_ERROR, ErrorType.PROTOCOL, ErrorTag.OPERATION_FAILED, "mock error", null, null);
- }
-
- @Test
- public void testToXMLResponseWithPartialOperationErrorTag() throws Exception {
-
- testXMLResponse(new RestconfDocumentedException("mock error", ErrorType.PROTOCOL, ErrorTag.PARTIAL_OPERATION),
- Status.INTERNAL_SERVER_ERROR, ErrorType.PROTOCOL, ErrorTag.PARTIAL_OPERATION, "mock error", null, null);
- }
-
- @Test
- public void testToXMLResponseWithErrorAppTag() throws Exception {
-
- testXMLResponse(new RestconfDocumentedException(new RestconfError(ErrorType.APPLICATION,
- ErrorTag.INVALID_VALUE, "mock error", "mock-app-tag")), Status.BAD_REQUEST, ErrorType.APPLICATION,
- ErrorTag.INVALID_VALUE, "mock error", "mock-app-tag", null);
- }
-
- @Test
- public void testToXMLResponseWithErrorInfo() throws Exception {
-
- final String errorInfo = "<address>1.2.3.4</address> <session-id>123</session-id>";
- testXMLResponse(new RestconfDocumentedException(new RestconfError(ErrorType.APPLICATION,
- ErrorTag.INVALID_VALUE, "mock error", "mock-app-tag", errorInfo)), Status.BAD_REQUEST,
- ErrorType.APPLICATION, ErrorTag.INVALID_VALUE, "mock error", "mock-app-tag",
- new SimpleErrorInfoVerifier(errorInfo));
- }
-
- @Test
- public void testToXMLResponseWithExceptionCause() throws Exception {
-
- final Exception cause = new Exception("mock exception cause");
- testXMLResponse(new RestconfDocumentedException("mock error", cause), Status.INTERNAL_SERVER_ERROR,
- ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, "mock error", null,
- new SimpleErrorInfoVerifier(cause.getMessage()));
- }
-
- @Test
- @Ignore // FIXME : find why it return error-type as RPC no APPLICATION
- public void testToXMLResponseWithMultipleErrors() throws Exception {
-
- final List<RestconfError> errorList = Arrays.asList(
- new RestconfError(ErrorType.APPLICATION, ErrorTag.LOCK_DENIED, "mock error1"),
- new RestconfError(ErrorType.RPC, ErrorTag.ROLLBACK_FAILED, "mock error2"));
- stageMockEx(new RestconfDocumentedException("mock", null, errorList));
-
- final Response resp = target("/operational/foo").request(MediaType.APPLICATION_XML).get();
-
- final InputStream stream = verifyResponse(resp, MediaType.APPLICATION_XML, Status.CONFLICT);
-
- final Document doc = parseXMLDocument(stream);
-
- final NodeList children = getXMLErrorList(doc, 2);
-
- verifyXMLErrorNode(children.item(0), ErrorType.APPLICATION, ErrorTag.LOCK_DENIED, "mock error1", null, null);
-
- verifyXMLErrorNode(children.item(1), ErrorType.RPC, ErrorTag.ROLLBACK_FAILED, "mock error2", null, null);
- }
-
- @Test
- public void testToResponseWithAcceptHeader() throws Exception {
-
- stageMockEx(new RestconfDocumentedException("mock error"));
-
- final Response resp = target("/operational/foo").request().header("Accept", MediaType.APPLICATION_JSON).get();
-
- final InputStream stream = verifyResponse(resp, MediaType.APPLICATION_JSON, Status.INTERNAL_SERVER_ERROR);
-
- verifyJsonResponseBody(stream, ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, "mock error", null, null);
- }
-
- @Test
- @Ignore
- public void testToResponseWithStatusOnly() throws Exception {
-
- // The StructuredDataToJsonProvider should throw a
- // RestconfDocumentedException with no data
-
- when(mockRestConf.readOperationalData(any(String.class), any(UriInfo.class))).thenReturn(
- new NormalizedNodeContext(null, null));
-
- final Response resp = target("/operational/foo").request(MediaType.APPLICATION_JSON).get();
-
- verifyResponse(resp, MediaType.TEXT_PLAIN, Status.NOT_FOUND);
- }
-
- InputStream verifyResponse(final Response resp, final String expMediaType, final Status expStatus) {
- assertEquals("getMediaType", MediaType.valueOf(expMediaType), resp.getMediaType());
- assertEquals("getStatus", expStatus.getStatusCode(), resp.getStatus());
-
- final Object entity = resp.getEntity();
- assertEquals("Response entity", true, entity instanceof InputStream);
- final InputStream stream = (InputStream) entity;
- return stream;
- }
-
- void verifyJsonResponseBody(final InputStream stream, final ErrorType expErrorType, final ErrorTag expErrorTag,
- final String expErrorMessage, final String expErrorAppTag, final ErrorInfoVerifier errorInfoVerifier)
- throws Exception {
-
- final JsonArray arrayElement = parseJsonErrorArrayElement(stream);
-
- assertEquals("\"error\" Json array element length", 1, arrayElement.size());
-
- verifyJsonErrorNode(arrayElement.get(0), expErrorType, expErrorTag, expErrorMessage, expErrorAppTag,
- errorInfoVerifier);
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- private static JsonArray parseJsonErrorArrayElement(final InputStream stream) throws IOException {
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- stream.transferTo(bos);
-
- LOG.info("JSON: {}", bos);
-
- JsonElement rootElement;
- try {
- rootElement = JsonParser.parseReader(new InputStreamReader(new ByteArrayInputStream(bos.toByteArray())));
- } catch (final Exception e) {
- throw new IllegalArgumentException("Invalid JSON response:\n" + bos.toString(), e);
- }
-
- assertTrue("Root element of Json is not an Object", rootElement.isJsonObject());
-
- final Set<Entry<String, JsonElement>> errorsEntrySet = rootElement.getAsJsonObject().entrySet();
- assertEquals("Json Object element set count", 1, errorsEntrySet.size());
-
- final Entry<String, JsonElement> errorsEntry = errorsEntrySet.iterator().next();
- final JsonElement errorsElement = errorsEntry.getValue();
- assertEquals("First Json element name", "errors", errorsEntry.getKey());
- assertTrue("\"errors\" Json element is not an Object", errorsElement.isJsonObject());
-
- final Set<Entry<String, JsonElement>> errorListEntrySet = errorsElement.getAsJsonObject().entrySet();
- assertEquals("Root \"errors\" element child count", 1, errorListEntrySet.size());
-
- final JsonElement errorListElement = errorListEntrySet.iterator().next().getValue();
- assertEquals("\"errors\" child Json element name", "error", errorListEntrySet.iterator().next().getKey());
- assertTrue("\"error\" Json element is not an Array", errorListElement.isJsonArray());
-
- // As a final check, make sure there aren't multiple "error" array
- // elements. Unfortunately,
- // the call above to getAsJsonObject().entrySet() will out duplicate
- // "error" elements. So
- // we'll use regex on the json string to verify this.
-
- final Matcher matcher = Pattern.compile("\"error\"[ ]*:[ ]*\\[", Pattern.DOTALL).matcher(bos.toString());
- assertTrue("Expected 1 \"error\" element", matcher.find());
- assertFalse("Found multiple \"error\" elements", matcher.find());
-
- return errorListElement.getAsJsonArray();
- }
-
- void verifyJsonErrorNode(final JsonElement errorEntryElement, final ErrorType expErrorType,
- final ErrorTag expErrorTag, final String expErrorMessage, final String expErrorAppTag,
- final ErrorInfoVerifier errorInfoVerifier) {
-
- JsonElement errorInfoElement = null;
- final Map<String, String> leafMap = new HashMap<>();
- for (final Entry<String, JsonElement> entry : errorEntryElement.getAsJsonObject().entrySet()) {
- final String leafName = entry.getKey();
- final JsonElement leafElement = entry.getValue();
-
- if ("error-info".equals(leafName)) {
- assertNotNull("Found unexpected \"error-info\" element", errorInfoVerifier);
- errorInfoElement = leafElement;
- } else {
- assertTrue("\"error\" leaf Json element " + leafName + " is not a Primitive",
- leafElement.isJsonPrimitive());
-
- leafMap.put(leafName, leafElement.getAsString());
- }
- }
-
- assertEquals("error-type", expErrorType.elementBody(), leafMap.remove("error-type"));
- assertEquals("error-tag", expErrorTag.elementBody(), leafMap.remove("error-tag"));
-
- verifyOptionalJsonLeaf(leafMap.remove("error-message"), expErrorMessage, "error-message");
- verifyOptionalJsonLeaf(leafMap.remove("error-app-tag"), expErrorAppTag, "error-app-tag");
-
- if (!leafMap.isEmpty()) {
- fail("Found unexpected Json leaf elements for \"error\" element: " + leafMap);
- }
-
- if (errorInfoVerifier != null) {
- assertNotNull("Missing \"error-info\" element", errorInfoElement);
- errorInfoVerifier.verifyJson(errorInfoElement);
- }
- }
-
- void verifyOptionalJsonLeaf(final String actualValue, final String expValue, final String tagName) {
- if (expValue != null) {
- assertEquals(tagName, expValue, actualValue);
- } else {
- assertNull("Found unexpected \"error\" leaf entry for: " + tagName, actualValue);
- }
- }
-
- void verifyXMLResponseBody(final InputStream stream, final ErrorType expErrorType, final ErrorTag expErrorTag,
- final String expErrorMessage, final String expErrorAppTag, final ErrorInfoVerifier errorInfoVerifier)
- throws Exception {
-
- final Document doc = parseXMLDocument(stream);
-
- final NodeList children = getXMLErrorList(doc, 1);
-
- verifyXMLErrorNode(children.item(0), expErrorType, expErrorTag, expErrorMessage, expErrorAppTag,
- errorInfoVerifier);
- }
-
- private static Document parseXMLDocument(final InputStream stream) throws IOException, SAXException {
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- stream.transferTo(bos);
-
- LOG.debug("XML: {}", bos);
-
- return UntrustedXML.newDocumentBuilder().parse(new ByteArrayInputStream(bos.toByteArray()));
- }
-
- void verifyXMLErrorNode(final Node errorNode, final ErrorType expErrorType, final ErrorTag expErrorTag,
- final String expErrorMessage, final String expErrorAppTag, final ErrorInfoVerifier errorInfoVerifier)
- throws Exception {
-
- final String errorType = (String) ERROR_TYPE.evaluate(errorNode, XPathConstants.STRING);
- assertEquals("error-type", expErrorType.elementBody(), errorType);
-
- final String errorTag = (String) ERROR_TAG.evaluate(errorNode, XPathConstants.STRING);
- assertEquals("error-tag", expErrorTag.elementBody(), errorTag);
-
- verifyOptionalXMLLeaf(errorNode, ERROR_MESSAGE, expErrorMessage, "error-message");
- verifyOptionalXMLLeaf(errorNode, ERROR_APP_TAG, expErrorAppTag, "error-app-tag");
-
- final Node errorInfoNode = (Node) ERROR_INFO.evaluate(errorNode, XPathConstants.NODE);
- if (errorInfoVerifier != null) {
- assertNotNull("Missing \"error-info\" node", errorInfoNode);
-
- errorInfoVerifier.verifyXML(errorInfoNode);
- } else {
- assertNull("Found unexpected \"error-info\" node", errorInfoNode);
- }
- }
-
- void verifyOptionalXMLLeaf(final Node fromNode, final XPathExpression xpath, final String expValue,
- final String tagName) throws Exception {
- if (expValue != null) {
- final String actual = (String) xpath.evaluate(fromNode, XPathConstants.STRING);
- assertEquals(tagName, expValue, actual);
- } else {
- assertNull("Found unexpected \"error\" leaf entry for: " + tagName,
- xpath.evaluate(fromNode, XPathConstants.NODE));
- }
- }
-
- NodeList getXMLErrorList(final Node fromNode, final int count) throws Exception {
- final NodeList errorList = (NodeList) ERROR_LIST.evaluate(fromNode, XPathConstants.NODESET);
- assertNotNull("Root errors node is empty", errorList);
- assertEquals("Root errors node child count", count, errorList.getLength());
- return errorList;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Brocade Communications 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.controller.sal.restconf.impl.test;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
-
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.junit.Test;
-import org.opendaylight.restconf.common.errors.RestconfError;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.common.ErrorType;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-
-/**
- * Unit tests for RestconfError.
- *
- * @author Devin Avery
- * @author Thomas Pantelis
- *
- */
-public class RestconfErrorTest {
-
- static class Contains extends BaseMatcher<String> {
-
- private final String text;
-
- Contains(final String text) {
- this.text = text;
- }
-
- @Override
- public void describeTo(final Description desc) {
- desc.appendText("contains ").appendValue(text);
- }
-
- @Override
- public boolean matches(final Object arg) {
- return arg != null && arg.toString().contains(text);
- }
- }
-
- @Test
- public void testRestConfDocumentedException_NoCause() {
- String expectedMessage = "Message";
- ErrorType expectedErrorType = ErrorType.RPC;
- ErrorTag expectedErrorTag = ErrorTag.IN_USE;
- RestconfError error = new RestconfError(expectedErrorType, expectedErrorTag, expectedMessage);
-
- validateRestConfError(expectedMessage, expectedErrorType, expectedErrorTag, null, (String) null, error);
- }
-
- @Test
- public void testRestConfDocumentedException_WithAppTag() {
- String expectedMessage = "Message";
- ErrorType expectedErrorType = ErrorType.RPC;
- ErrorTag expectedErrorTag = ErrorTag.IN_USE;
- String expectedErrorAppTag = "application.tag";
-
- RestconfError error =
- new RestconfError(expectedErrorType, expectedErrorTag, expectedMessage, expectedErrorAppTag);
-
- validateRestConfError(expectedMessage, expectedErrorType, expectedErrorTag, expectedErrorAppTag, (String) null,
- error);
- }
-
- @Test
- public void testRestConfDocumentedException_WithAppTagErrorInfo() {
- String expectedMessage = "Message";
- ErrorType expectedErrorType = ErrorType.RPC;
- ErrorTag expectedErrorTag = ErrorTag.IN_USE;
- String expectedErrorAppTag = "application.tag";
- String errorInfo = "<extra><sessionid>session.id</sessionid></extra>";
-
- RestconfError error =
- new RestconfError(expectedErrorType, expectedErrorTag, expectedMessage, expectedErrorAppTag, errorInfo);
-
- validateRestConfError(expectedMessage, expectedErrorType, expectedErrorTag, expectedErrorAppTag, errorInfo,
- error);
- }
-
- @Test
- public void testRestConfErrorWithRpcError() {
-
- // All fields set
- RpcError rpcError = RpcResultBuilder.newError(ErrorType.PROTOCOL, ErrorTag.BAD_ATTRIBUTE, "mock error-message",
- "mock app-tag", "mock error-info", new Exception("mock cause"));
-
- validateRestConfError("mock error-message", ErrorType.PROTOCOL, ErrorTag.BAD_ATTRIBUTE, "mock app-tag",
- "mock error-info", new RestconfError(rpcError));
-
- // All fields set except 'info' - expect error-info set to 'cause'
- rpcError = RpcResultBuilder.newError(ErrorType.PROTOCOL, ErrorTag.BAD_ATTRIBUTE, "mock error-message",
- "mock app-tag", null, new Exception("mock cause"));
-
- validateRestConfError("mock error-message", ErrorType.PROTOCOL, ErrorTag.BAD_ATTRIBUTE, "mock app-tag",
- new Contains("mock cause"), new RestconfError(rpcError));
-
- // Some fields set - expect error-info set to ErrorSeverity
- rpcError = RpcResultBuilder.newError(ErrorType.RPC, ErrorTag.ACCESS_DENIED, null, null, null, null);
-
- validateRestConfError(null, ErrorType.RPC, ErrorTag.ACCESS_DENIED, null, "<severity>error</severity>",
- new RestconfError(rpcError));
-
- // 'tag' field not mapped to ErrorTag - expect error-tag set to OPERATION_FAILED
- rpcError = RpcResultBuilder.newWarning(ErrorType.TRANSPORT, new ErrorTag("not mapped"), null, null, null, null);
-
- validateRestConfError(null, ErrorType.TRANSPORT, new ErrorTag("not mapped"), null,
- "<severity>warning</severity>", new RestconfError(rpcError));
-
- // No fields set - edge case
- rpcError = RpcResultBuilder.newError(ErrorType.APPLICATION, null, null, null, null, null);
-
- validateRestConfError(null, ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED,
- null, "<severity>error</severity>", new RestconfError(rpcError));
- }
-
- private static void validateRestConfError(final String expectedMessage, final ErrorType expectedErrorType,
- final ErrorTag expectedErrorTag, final String expectedErrorAppTag, final String errorInfo,
- final RestconfError error) {
-
- validateRestConfError(expectedMessage, expectedErrorType, expectedErrorTag, expectedErrorAppTag,
- equalTo(errorInfo), error);
- }
-
- private static void validateRestConfError(final String expectedMessage, final ErrorType expectedErrorType,
- final ErrorTag expectedErrorTag, final String expectedErrorAppTag, final Matcher<String> errorInfoMatcher,
- final RestconfError error) {
-
- assertEquals("getErrorMessage", expectedMessage, error.getErrorMessage());
- assertEquals("getErrorType", expectedErrorType, error.getErrorType());
- assertEquals("getErrorTag", expectedErrorTag, error.getErrorTag());
- assertEquals("getErrorAppTag", expectedErrorAppTag, error.getErrorAppTag());
- assertThat("getErrorInfo", error.getErrorInfo(), errorInfoMatcher);
- error.toString(); // really just checking for NPE etc. Don't care about
- // contents.
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.io.FileNotFoundException;
-import java.time.Instant;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.UriBuilder;
-import javax.ws.rs.core.UriInfo;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.netconf.sal.restconf.impl.BrokerFacade;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.netconf.sal.restconf.impl.RestconfImpl;
-import org.opendaylight.netconf.sal.streams.listeners.ListenerAdapter;
-import org.opendaylight.netconf.sal.streams.listeners.Notificator;
-import org.opendaylight.netconf.sal.streams.websockets.WebSocketServer;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping.NotificationOutputType;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
-
-@RunWith(MockitoJUnitRunner.StrictStubs.class)
-public class RestconfImplNotificationSubscribingTest {
-
- private final String identifier = "data-change-event-subscription/datastore=OPERATIONAL/scope=ONE";
-
- private static EffectiveModelContext schemaContext;
-
- @Mock
- private BrokerFacade broker;
-
- @Mock
- private UriInfo uriInfo;
-
- private ControllerContext controllerContext;
- private RestconfImpl restconfImpl;
-
- @BeforeClass
- public static void init() throws FileNotFoundException {
- schemaContext = YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles("/notifications"));
- }
-
- @AfterClass
- public static void cleanUp() {
- WebSocketServer.destroyInstance(); // NETCONF-604
- }
-
- @Before
- public void setup() {
- controllerContext = TestRestconfUtils.newControllerContext(schemaContext);
- restconfImpl = RestconfImpl.newInstance(broker, controllerContext);
-
- final YangInstanceIdentifier path = mock(YangInstanceIdentifier.class);
- Notificator.createListener(path, identifier, NotificationOutputType.XML, controllerContext);
- }
-
- @Test
- public void startTimeTest() {
- subscribe(Set.of(Map.entry("start-time", List.of("2014-10-25T10:02:00Z"))));
- Notificator.removeAllListeners();
- }
-
- @Test
- public void milisecsTest() {
- subscribe(Set.of(Map.entry("start-time", List.of("2014-10-25T10:02:00.12345Z"))));
- Notificator.removeAllListeners();
- }
-
- @Test
- public void zonesPlusTest() {
- subscribe(Set.of(Map.entry("start-time", List.of("2014-10-25T10:02:00+01:00"))));
- Notificator.removeAllListeners();
- }
-
- @Test
- public void zonesMinusTest() {
- subscribe(Set.of(Map.entry("start-time", List.of("2014-10-25T10:02:00-01:00"))));
- Notificator.removeAllListeners();
- }
-
- @Test
- public void startAndStopTimeTest() {
- subscribe(Set.of(Map.entry("start-time", List.of("2014-10-25T10:02:00Z")),
- Map.entry("stop-time", List.of("2014-10-25T12:31:00Z"))));
- Notificator.removeAllListeners();
- }
-
- @Test(expected = RestconfDocumentedException.class)
- public void stopTimeTest() {
- subscribe(Set.of(Map.entry("stop-time", List.of("2014-10-25T12:31:00Z"))));
- Notificator.removeAllListeners();
- }
-
- @Test(expected = RestconfDocumentedException.class)
- public void badParamTest() {
- subscribe(Set.of(Map.entry("time", List.of("2014-10-25T12:31:00Z"))));
- Notificator.removeAllListeners();
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void badValueTest() {
- subscribe(Set.of(Map.entry("start-time", List.of("badvalue"))));
- Notificator.removeAllListeners();
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void badZonesTest() {
- subscribe(Set.of(Map.entry("start-time", List.of("2014-10-25T10:02:00Z+1:00"))));
- Notificator.removeAllListeners();
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void badMilisecsTest() {
- subscribe(Set.of(Map.entry("start-time", List.of("2014-10-25T10:02:00:0026Z"))));
- Notificator.removeAllListeners();
- }
-
- @Test
- public void onNotifiTest() throws Exception {
- final YangInstanceIdentifier path = mock(YangInstanceIdentifier.class);
- final PathArgument pathValue = NodeIdentifier.create(QName.create("module", "2016-12-14", "localName"));
- final ListenerAdapter listener = Notificator.createListener(path, identifier, NotificationOutputType.XML,
- controllerContext);
-
- subscribe(Set.of(Map.entry("start-time", List.of("2014-10-25T10:02:00Z"))));
-
- Instant startOrig = listener.getStart();
- assertNotNull(startOrig);
- listener.onDataTreeChanged(List.of());
-
- startOrig = listener.getStart();
- assertNull(startOrig);
- }
-
- private void subscribe(final Set<Entry<String, List<String>>> entries) {
- final MultivaluedMap<String, String> map = mock(MultivaluedMap.class);
- when(uriInfo.getQueryParameters()).thenReturn(map);
- final UriBuilder uriBuilder = UriBuilder.fromPath("http://localhost:8181/" + identifier);
- when(uriInfo.getAbsolutePathBuilder()).thenReturn(uriBuilder);
- when(map.entrySet()).thenReturn(entries);
- restconfImpl.subscribeToStream(identifier, uriInfo);
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.withSettings;
-import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFluentFuture;
-
-import java.io.FileNotFoundException;
-import java.net.URI;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Optional;
-import java.util.Set;
-import javax.ws.rs.core.MultivaluedHashMap;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.UriBuilder;
-import javax.ws.rs.core.UriInfo;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.mdsal.dom.api.DOMMountPoint;
-import org.opendaylight.mdsal.dom.api.DOMRpcResult;
-import org.opendaylight.mdsal.dom.api.DOMRpcService;
-import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
-import org.opendaylight.netconf.sal.rest.api.Draft02;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.restconf.impl.BrokerFacade;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.netconf.sal.restconf.impl.RestconfImpl;
-import org.opendaylight.netconf.sal.streams.listeners.Notificator;
-import org.opendaylight.netconf.sal.streams.websockets.WebSocketServer;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.errors.RestconfError;
-import org.opendaylight.yangtools.yang.common.Empty;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.common.ErrorType;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.YangConstants;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.SchemaAwareBuilders;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.InputSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.OutputSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.stmt.InputEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.OutputEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.RpcEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
-
-/**
- * See {@link InvokeRpcMethodTest}.
- */
-public class RestconfImplTest {
-
- private static EffectiveModelContext schemaContext;
-
- private final BrokerFacade brokerFacade = mock(BrokerFacade.class);
- private final ControllerContext controllerContext = TestRestconfUtils.newControllerContext(schemaContext);
- private final RestconfImpl restconfImpl = RestconfImpl.newInstance(brokerFacade, controllerContext);
-
- @BeforeClass
- public static void init() throws FileNotFoundException, ReactorException {
- schemaContext = TestUtils.loadSchemaContext("/full-versions/yangs", "/modules/restconf-module-testing");
- }
-
- @AfterClass
- public static void cleanUp() {
- WebSocketServer.destroyInstance(); // NETCONF-604
- }
-
- @Test
- public void binaryKeyTest() {
- final List<Byte> al = new ArrayList<>();
- al.add((byte) 1);
- binaryKeyTest(al, al);
- }
-
- private static void binaryKeyTest(final List<Byte> al, final List<Byte> al2) {
-
- final QName keyDef = QName.create("test:key:binary", "2017-08-14", "b1");
-
- final Map<QName, Object> uriKeyValues = new HashMap<>();
- uriKeyValues.put(keyDef, al.toArray());
-
- final MapEntryNode payload = mock(MapEntryNode.class);
- final NodeIdentifierWithPredicates nodeIdWithPred =
- NodeIdentifierWithPredicates.of(keyDef, keyDef, al2.toArray());
- when(payload.getIdentifier()).thenReturn(nodeIdWithPred);
-
- final List<QName> keyDefinitions = new ArrayList<>();
- keyDefinitions.add(keyDef);
- RestconfImpl.isEqualUriAndPayloadKeyValues(uriKeyValues, payload, keyDefinitions);
- }
-
- @Test
- public void binaryKeyFailTest() {
- final List<Byte> al = new ArrayList<>();
- al.add((byte) 1);
- final List<Byte> al2 = new ArrayList<>();
- try {
- binaryKeyTest(al, al2);
- } catch (final RestconfDocumentedException e) {
- final RestconfError err = e.getErrors().iterator().next();
- assertEquals(ErrorType.PROTOCOL, err.getErrorType());
- assertEquals(ErrorTag.INVALID_VALUE, err.getErrorTag());
- }
- }
-
- @Test
- public void testExample() throws FileNotFoundException, ParseException {
- final NormalizedNode normalizedNodeData = TestUtils.prepareNormalizedNodeWithIetfInterfacesInterfacesData();
- when(brokerFacade.readOperationalData(isNull())).thenReturn(normalizedNodeData);
- assertEquals(normalizedNodeData,
- brokerFacade.readOperationalData(null));
- }
-
- @Test
- public void testRpcForMountpoint() throws Exception {
- final QName qname = QName.create("namespace", "2010-10-10", "localname");
- final UriInfo uriInfo = mock(UriInfo.class);
- doReturn(new MultivaluedHashMap<>()).when(uriInfo).getQueryParameters(anyBoolean());
-
- final NormalizedNodeContext ctx = mock(NormalizedNodeContext.class);
- final RpcDefinition rpc = mock(RpcDefinition.class,
- withSettings().extraInterfaces(RpcEffectiveStatement.class));
- doReturn(qname).when(rpc).getQName();
-
- final InputSchemaNode input = mock(InputSchemaNode.class,
- withSettings().extraInterfaces(InputEffectiveStatement.class));
- final QName inputQName = YangConstants.operationInputQName(qname.getModule());
- doReturn(input).when(rpc).getInput();
- doReturn(inputQName).when(input).getQName();
- doReturn(Optional.of(input)).when((RpcEffectiveStatement) rpc).findSchemaTreeNode(inputQName);
-
- final OutputSchemaNode output = mock(OutputSchemaNode.class,
- withSettings().extraInterfaces(OutputEffectiveStatement.class));
- final QName outputQName = YangConstants.operationInputQName(qname.getModule());
- doReturn(output).when(rpc).getOutput();
- doReturn(outputQName).when(output).getQName();
- doReturn(Optional.of(output)).when((RpcEffectiveStatement) rpc).findSchemaTreeNode(outputQName);
-
- final EffectiveModelContext mountContext = mock(EffectiveModelContext.class);
- final ModuleEffectiveStatement mountModule = mock(ModuleEffectiveStatement.class);
- doReturn(Map.of(qname.getModule(), mountModule)).when(mountContext).getModuleStatements();
- doReturn(Optional.of(rpc)).when(mountModule).findSchemaTreeNode(qname);
-
- final DOMMountPoint mount = mock(DOMMountPoint.class);
- doReturn(Optional.of(FixedDOMSchemaService.of(mountContext))).when(mount).getService(DOMSchemaService.class);
-
- doReturn(InstanceIdentifierContext.ofRpcInput(mountContext, rpc, mount))
- .when(ctx).getInstanceIdentifierContext();
-
- final DOMRpcService rpcService = mock(DOMRpcService.class);
- doReturn(Optional.of(rpcService)).when(mount).getService(DOMRpcService.class);
- doReturn(immediateFluentFuture(mock(DOMRpcResult.class))).when(rpcService)
- .invokeRpc(any(QName.class), any(NormalizedNode.class));
- restconfImpl.invokeRpc("randomId", ctx, uriInfo);
- restconfImpl.invokeRpc("ietf-netconf", ctx, uriInfo);
- verify(rpcService, times(2)).invokeRpc(any(QName.class), any());
- }
-
- /**
- * Create notification stream for toaster module.
- */
- @Test
- public void createNotificationStreamTest() {
- final QName rpcQName = QName.create("urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote",
- "2014-01-14", "create-notification-stream");
-
- final RpcDefinition schemaNode = schemaContext.getOperations().stream()
- .filter(rpc -> rpc.getQName().equals(rpcQName))
- .findFirst()
- .orElseThrow();
-
- final NormalizedNodeContext payload = mock(NormalizedNodeContext.class);
- doReturn(InstanceIdentifierContext.ofRpcInput(schemaContext, schemaNode, null)).when(payload)
- .getInstanceIdentifierContext();
-
- final Set<DataContainerChild> children = new HashSet<>();
- final LeafSetNode child = mock(LeafSetNode.class);
-
- final LeafSetEntryNode entryNode = mock(LeafSetEntryNode.class);
- when(entryNode.body()).thenReturn("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)toastDone");
- when(child.body()).thenReturn(Set.of(entryNode));
- children.add(child);
-
- final ContainerNode normalizedNode = mock(ContainerNode.class);
- doReturn(normalizedNode).when(payload).getData();
- doReturn(children).when(normalizedNode).body();
-
- // register notification
- final NormalizedNodeContext context = restconfImpl
- .invokeRpc("sal-remote:create-notification-stream", payload, null);
- assertNotNull(context);
- }
-
- /**
- * Tests stream entry node.
- */
- @Test
- public void toStreamEntryNodeTest() {
- final Module restconfModule = controllerContext.getRestconfModule();
- final DataSchemaNode streamSchemaNode = controllerContext
- .getRestconfModuleRestConfSchemaNode(restconfModule, Draft02.RestConfModule.STREAM_LIST_SCHEMA_NODE);
- final ListSchemaNode listStreamSchemaNode = (ListSchemaNode) streamSchemaNode;
- final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> streamNodeValues =
- SchemaAwareBuilders.mapEntryBuilder(listStreamSchemaNode);
- var instanceDataChildrenByName =
- ControllerContext.findInstanceDataChildrenByName(listStreamSchemaNode, "name");
- final DataSchemaNode nameSchemaNode = instanceDataChildrenByName.get(0).child;
- streamNodeValues.withChild(SchemaAwareBuilders.leafBuilder((LeafSchemaNode) nameSchemaNode)
- .withValue("")
- .build());
-
- instanceDataChildrenByName =
- ControllerContext.findInstanceDataChildrenByName(listStreamSchemaNode, "description");
- final DataSchemaNode descriptionSchemaNode = instanceDataChildrenByName.get(0).child;
- streamNodeValues.withChild(SchemaAwareBuilders.leafBuilder((LeafSchemaNode) nameSchemaNode)
- .withValue("DESCRIPTION_PLACEHOLDER")
- .build());
-
- instanceDataChildrenByName =
- ControllerContext.findInstanceDataChildrenByName(listStreamSchemaNode, "replay-support");
- final DataSchemaNode replaySupportSchemaNode = instanceDataChildrenByName.get(0).child;
- streamNodeValues.withChild(
- SchemaAwareBuilders.leafBuilder((LeafSchemaNode) replaySupportSchemaNode).withValue(Boolean.TRUE).build());
-
- instanceDataChildrenByName =
- ControllerContext.findInstanceDataChildrenByName(listStreamSchemaNode, "replay-log-creation-time");
- final DataSchemaNode replayLogCreationTimeSchemaNode = instanceDataChildrenByName.get(0).child;
- streamNodeValues.withChild(
- SchemaAwareBuilders.leafBuilder((LeafSchemaNode) replayLogCreationTimeSchemaNode).withValue("").build());
- instanceDataChildrenByName = ControllerContext.findInstanceDataChildrenByName(listStreamSchemaNode, "events");
- final DataSchemaNode eventsSchemaNode = instanceDataChildrenByName.get(0).child;
- streamNodeValues.withChild(
- SchemaAwareBuilders.leafBuilder((LeafSchemaNode) eventsSchemaNode).withValue(Empty.value()).build());
- assertNotNull(streamNodeValues.build());
- }
-
- /**
- * Subscribe for notification stream of toaster module.
- */
- @Test
- public void subscribeToNotificationStreamTest() throws Exception {
- final String identifier = "create-notification-stream/toaster:toastDone";
-
- // register test notification stream
- Notificator.createNotificationListener(
- List.of(Absolute.of(QName.create("http://netconfcentral.org/ns/toaster", "2009-11-20", "toastDone"))),
- identifier, "XML", controllerContext);
-
- final UriInfo uriInfo = mock(UriInfo.class);
- final UriBuilder uriBuilder = mock(UriBuilder.class);
- when(uriBuilder.port(8181)).thenReturn(uriBuilder);
- when(uriBuilder.replacePath(identifier)).thenReturn(uriBuilder);
- when(uriBuilder.build()).thenReturn(new URI(""));
- when(uriBuilder.scheme("ws")).thenReturn(uriBuilder);
- when(uriInfo.getAbsolutePathBuilder()).thenReturn(uriBuilder);
- final MultivaluedMap<String, String> map = mock(MultivaluedMap.class);
- final Set<Entry<String, List<String>>> set = new HashSet<>();
- when(map.entrySet()).thenReturn(set);
- when(uriInfo.getQueryParameters()).thenReturn(map);
-
- // subscribe to stream and verify response
- final NormalizedNodeContext response = restconfImpl.subscribeToStream(identifier, uriInfo);
-
- // remove test notification stream
- Notificator.removeAllListeners();
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static java.util.Objects.requireNonNull;
-import static org.junit.Assert.assertNotNull;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStreamWriter;
-import java.nio.charset.StandardCharsets;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-import org.opendaylight.yangtools.util.xml.UntrustedXML;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.Revision;
-import org.opendaylight.yangtools.yang.common.XMLNamespace;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-public final class TestUtils {
-
- private static final Logger LOG = LoggerFactory.getLogger(TestUtils.class);
-
- private TestUtils() {
-
- }
-
- public static EffectiveModelContext loadSchemaContext(final String... yangPath) throws FileNotFoundException {
- final List<File> files = new ArrayList<>();
- for (final String path : yangPath) {
- final String pathToFile = TestUtils.class.getResource(path).getPath();
- final File testDir = new File(pathToFile);
- final String[] fileList = testDir.list();
- if (fileList == null) {
- throw new FileNotFoundException(pathToFile);
- }
-
- for (final String fileName : fileList) {
- final File file = new File(testDir, fileName);
- if (file.isDirectory() == false) {
- files.add(file);
- }
- }
- }
-
- return YangParserTestUtils.parseYangFiles(files);
- }
-
- public static Module findModule(final Collection<? extends Module> modules, final String moduleName) {
- for (final Module module : modules) {
- if (module.getName().equals(moduleName)) {
- return module;
- }
- }
- return null;
- }
-
- public static Document loadDocumentFrom(final InputStream inputStream) {
- try {
- return UntrustedXML.newDocumentBuilder().parse(inputStream);
- } catch (SAXException | IOException e) {
- LOG.error("Error during loading Document from XML", e);
- return null;
- }
- }
-
- public static String getDocumentInPrintableForm(final Document doc) {
- try {
- final ByteArrayOutputStream out = new ByteArrayOutputStream();
- final TransformerFactory tf = TransformerFactory.newInstance();
- final Transformer transformer = tf.newTransformer();
- transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
- transformer.setOutputProperty(OutputKeys.METHOD, "xml");
- transformer.setOutputProperty(OutputKeys.INDENT, "yes");
- transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
- transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
-
- transformer.transform(new DOMSource(requireNonNull(doc)), new StreamResult(new OutputStreamWriter(out,
- StandardCharsets.UTF_8)));
- final byte[] charData = out.toByteArray();
- return new String(charData, StandardCharsets.UTF_8);
- } catch (final TransformerException e) {
- final String msg = "Error during transformation of Document into String";
- LOG.error(msg, e);
- return msg;
- }
-
- }
-
- /**
- * Searches module with name {@code searchedModuleName} in {@code modules}. If module name isn't specified and
- * module set has only one element then this element is returned.
- *
- */
- public static Module resolveModule(final String searchedModuleName, final Collection<? extends Module> modules) {
- assertNotNull("Modules can't be null.", modules);
- if (searchedModuleName != null) {
- for (final Module m : modules) {
- if (m.getName().equals(searchedModuleName)) {
- return m;
- }
- }
- } else if (modules.size() == 1) {
- return modules.iterator().next();
- }
- return null;
- }
-
- public static DataSchemaNode resolveDataSchemaNode(final String searchedDataSchemaName, final Module module) {
- assertNotNull("Module can't be null", module);
-
- if (searchedDataSchemaName != null) {
- for (final DataSchemaNode dsn : module.getChildNodes()) {
- if (dsn.getQName().getLocalName().equals(searchedDataSchemaName)) {
- return dsn;
- }
- }
- } else if (module.getChildNodes().size() == 1) {
- return module.getChildNodes().iterator().next();
- }
- return null;
- }
-
- public static QName buildQName(final String name, final String uri, final String date, final String prefix) {
- return QName.create(XMLNamespace.of(uri), Revision.ofNullable(date), name);
- }
-
- public static QName buildQName(final String name, final String uri, final String date) {
- return buildQName(name, uri, date, null);
- }
-
- public static QName buildQName(final String name) {
- return buildQName(name, "", null);
- }
-
- public static String loadTextFile(final String filePath) throws IOException {
- final FileReader fileReader = new FileReader(filePath, StandardCharsets.UTF_8);
- final BufferedReader bufReader = new BufferedReader(fileReader);
-
- String line = null;
- final StringBuilder result = new StringBuilder();
- while ((line = bufReader.readLine()) != null) {
- result.append(line);
- }
- bufReader.close();
- return result.toString();
- }
-
- private static Pattern patternForStringsSeparatedByWhiteChars(final String... substrings) {
- final StringBuilder pattern = new StringBuilder();
- pattern.append(".*");
- for (final String substring : substrings) {
- pattern.append(substring);
- pattern.append("\\s*");
- }
- pattern.append(".*");
- return Pattern.compile(pattern.toString(), Pattern.DOTALL);
- }
-
- public static boolean containsStringData(final String jsonOutput, final String... substrings) {
- final Pattern pattern = patternForStringsSeparatedByWhiteChars(substrings);
- final Matcher matcher = pattern.matcher(jsonOutput);
- return matcher.matches();
- }
-
- public static NodeIdentifier getNodeIdentifier(final String localName, final String namespace,
- final String revision) throws ParseException {
- return new NodeIdentifier(QName.create(namespace, revision, localName));
- }
-
- public static NodeIdentifierWithPredicates getNodeIdentifierPredicate(final String localName,
- final String namespace, final String revision, final Map<String, Object> keys) throws ParseException {
- final Map<QName, Object> predicate = new HashMap<>();
- for (final String key : keys.keySet()) {
- predicate.put(QName.create(namespace, revision, key), keys.get(key));
- }
-
- return NodeIdentifierWithPredicates.of(QName.create(namespace, revision, localName), predicate);
- }
-
- public static NodeIdentifierWithPredicates getNodeIdentifierPredicate(final String localName,
- final String namespace, final String revision, final String... keysAndValues) throws ParseException {
- checkArgument(keysAndValues.length % 2 == 0, "number of keys argument have to be divisible by 2 (map)");
- final Map<QName, Object> predicate = new HashMap<>();
-
- int index = 0;
- while (index < keysAndValues.length) {
- predicate.put(QName.create(namespace, revision, keysAndValues[index++]), keysAndValues[index++]);
- }
-
- return NodeIdentifierWithPredicates.of(QName.create(namespace, revision, localName), predicate);
- }
-
- public static NormalizedNode prepareNormalizedNodeWithIetfInterfacesInterfacesData() throws ParseException {
- final String ietfInterfacesDate = "2013-07-04";
- final String namespace = "urn:ietf:params:xml:ns:yang:ietf-interfaces";
- final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryNode =
- ImmutableMapEntryNodeBuilder.create();
-
- final Map<String, Object> predicates = new HashMap<>();
- predicates.put("name", "eth0");
-
- mapEntryNode.withNodeIdentifier(getNodeIdentifierPredicate("interface", namespace, ietfInterfacesDate,
- predicates));
- mapEntryNode
- .withChild(new ImmutableLeafNodeBuilder<String>()
- .withNodeIdentifier(getNodeIdentifier("name", namespace, ietfInterfacesDate)).withValue("eth0")
- .build());
- mapEntryNode.withChild(new ImmutableLeafNodeBuilder<String>()
- .withNodeIdentifier(getNodeIdentifier("type", namespace, ietfInterfacesDate))
- .withValue("ethernetCsmacd").build());
- mapEntryNode.withChild(new ImmutableLeafNodeBuilder<Boolean>()
- .withNodeIdentifier(getNodeIdentifier("enabled", namespace, ietfInterfacesDate))
- .withValue(Boolean.FALSE).build());
- mapEntryNode.withChild(new ImmutableLeafNodeBuilder<String>()
- .withNodeIdentifier(getNodeIdentifier("description", namespace, ietfInterfacesDate))
- .withValue("some interface").build());
-
- return mapEntryNode.build();
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-import static java.util.Objects.requireNonNull;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.io.FileNotFoundException;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.UriBuilder;
-import javax.ws.rs.core.UriInfo;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.restconf.impl.BrokerFacade;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.netconf.sal.restconf.impl.RestconfImpl;
-import org.opendaylight.netconf.sal.streams.listeners.ListenerAdapter;
-import org.opendaylight.netconf.sal.streams.listeners.Notificator;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.CreateDataChangeEventSubscriptionInput1.Scope;
-import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping.NotificationOutputType;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.Revision;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.InstanceIdentifierBuilder;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.SchemaAwareBuilders;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerLike;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.InputSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
-
-public class URIParametersParsing {
-
- private RestconfImpl restconf;
- private BrokerFacade mockedBrokerFacade;
- private ControllerContext controllerContext;
-
- @Before
- public void init() throws FileNotFoundException, ReactorException {
- mockedBrokerFacade = mock(BrokerFacade.class);
- controllerContext = TestRestconfUtils.newControllerContext(
- TestUtils.loadSchemaContext("/datastore-and-scope-specification"));
- restconf = RestconfImpl.newInstance(mockedBrokerFacade, controllerContext);
- }
-
- @Test
- public void resolveURIParametersConcreteValues() {
- resolveURIParameters("OPERATIONAL", "SUBTREE", LogicalDatastoreType.OPERATIONAL, Scope.SUBTREE);
- }
-
- @Test
- public void resolveURIParametersDefaultValues() {
- resolveURIParameters(null, null, LogicalDatastoreType.CONFIGURATION, Scope.BASE);
- }
-
- private void resolveURIParameters(final String datastore, final String scope,
- final LogicalDatastoreType datastoreExpected, final Scope scopeExpected) {
-
- final InstanceIdentifierBuilder iiBuilder = YangInstanceIdentifier.builder();
- iiBuilder.node(QName.create("", "dummyStreamName"));
-
- final String datastoreValue = datastore == null ? "CONFIGURATION" : datastore;
- final String scopeValue = scope == null ? "BASE" : scope + "";
- Notificator.createListener(iiBuilder.build(), "dummyStreamName/datastore=" + datastoreValue + "/scope="
- + scopeValue, NotificationOutputType.XML, controllerContext);
-
- final UriInfo mockedUriInfo = mock(UriInfo.class);
- @SuppressWarnings("unchecked")
- final MultivaluedMap<String, String> mockedMultivaluedMap = mock(MultivaluedMap.class);
- when(mockedMultivaluedMap.getFirst(eq("datastore"))).thenReturn(datastoreValue);
- when(mockedMultivaluedMap.getFirst(eq("scope"))).thenReturn(scopeValue);
-
- when(mockedUriInfo.getQueryParameters(eq(false))).thenReturn(mockedMultivaluedMap);
-
- final UriBuilder uriBuilder = UriBuilder.fromUri("www.whatever.com");
- when(mockedUriInfo.getAbsolutePathBuilder()).thenReturn(uriBuilder);
-
- restconf.invokeRpc("sal-remote:create-data-change-event-subscription",
- prepareDomRpcNode(datastoreValue, scopeValue), mockedUriInfo);
-
- final ListenerAdapter listener =
- Notificator.getListenerFor("data-change-event-subscription/opendaylight-inventory:nodes/datastore="
- + datastoreValue + "/scope=" + scopeValue);
- assertNotNull(listener);
- }
-
- private NormalizedNodeContext prepareDomRpcNode(final String datastore, final String scope) {
- final EffectiveModelContext schema = controllerContext.getGlobalSchema();
- final Module rpcSalRemoteModule = schema.findModule("sal-remote", Revision.of("2014-01-14")).get();
- final QName rpcQName =
- QName.create(rpcSalRemoteModule.getQNameModule(), "create-data-change-event-subscription");
- final RpcDefinition rpcDef = Mockito.mock(RpcDefinition.class);
- ContainerLike rpcInputSchemaNode = null;
- for (final RpcDefinition rpc : rpcSalRemoteModule.getRpcs()) {
- if (rpcQName.isEqualWithoutRevision(rpc.getQName())) {
- rpcInputSchemaNode = rpc.getInput();
- break;
- }
- }
- assertNotNull("RPC ContainerSchemaNode was not found!", rpcInputSchemaNode);
-
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> container =
- SchemaAwareBuilders.containerBuilder(rpcInputSchemaNode);
-
- final QName pathQName =
- QName.create("urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote", "2014-01-14", "path");
- final DataSchemaNode pathSchemaNode = rpcInputSchemaNode.getDataChildByName(pathQName);
- assertTrue(pathSchemaNode instanceof LeafSchemaNode);
- final LeafNode<Object> pathNode = SchemaAwareBuilders.leafBuilder((LeafSchemaNode) pathSchemaNode)
- .withValue(YangInstanceIdentifier.builder()
- .node(QName.create("urn:opendaylight:inventory", "2013-08-19", "nodes")).build()).build();
- container.withChild(pathNode);
-
- final AugmentationSchemaNode augmentationSchema = requireNonNull(rpcInputSchemaNode.getAvailableAugmentations()
- .iterator().next());
- final DataContainerNodeBuilder<AugmentationIdentifier, AugmentationNode> augmentationBuilder =
- SchemaAwareBuilders.augmentationBuilder(augmentationSchema);
-
- final QName dataStoreQName = QName.create("urn:sal:restconf:event:subscription", "2014-07-08", "datastore");
- final DataSchemaNode dsSchemaNode = augmentationSchema.getDataChildByName(dataStoreQName);
- assertTrue(dsSchemaNode instanceof LeafSchemaNode);
- final LeafNode<Object> dsNode = SchemaAwareBuilders.leafBuilder((LeafSchemaNode) dsSchemaNode)
- .withValue(datastore).build();
- augmentationBuilder.withChild(dsNode);
-
- final QName scopeQName = QName.create("urn:sal:restconf:event:subscription", "2014-07-08", "scope");
- final DataSchemaNode scopeSchemaNode = augmentationSchema.getDataChildByName(scopeQName);
- assertTrue(scopeSchemaNode instanceof LeafSchemaNode);
- final LeafNode<Object> scopeNode = SchemaAwareBuilders.leafBuilder((LeafSchemaNode) scopeSchemaNode)
- .withValue(scope).build();
- augmentationBuilder.withChild(scopeNode);
-
- final QName outputQName =
- QName.create("urn:sal:restconf:event:subscription", "2014-07-08", "notification-output-type");
- final DataSchemaNode outputSchemaNode = augmentationSchema.getDataChildByName(outputQName);
- assertTrue(outputSchemaNode instanceof LeafSchemaNode);
- final LeafNode<Object> outputNode =
- SchemaAwareBuilders.leafBuilder((LeafSchemaNode) outputSchemaNode).withValue("XML").build();
- augmentationBuilder.withChild(outputNode);
-
- container.withChild(augmentationBuilder.build());
-
- when(rpcDef.getInput()).thenReturn((InputSchemaNode) rpcInputSchemaNode);
- when(rpcDef.getQName()).thenReturn(rpcQName);
-
- return new NormalizedNodeContext(InstanceIdentifierContext.ofRpcInput(schema, rpcDef, null), container.build());
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import java.io.FileNotFoundException;
-import java.util.Optional;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.mdsal.dom.api.DOMMountPoint;
-import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
-
-public class URITest {
-
- private static EffectiveModelContext schemaContext;
- private static EffectiveModelContext mountSchemaContext;
-
- private final DOMMountPoint mountInstance = mock(DOMMountPoint.class);
- private final ControllerContext controllerContext =
- TestRestconfUtils.newControllerContext(schemaContext, mountInstance);
-
- @BeforeClass
- public static void init() throws FileNotFoundException, ReactorException {
- schemaContext = TestUtils.loadSchemaContext("/full-versions/yangs");
- mountSchemaContext = TestUtils.loadSchemaContext("/test-config-data/yang2");
- }
-
- @Test
- public void testToInstanceIdentifierList() {
- InstanceIdentifierContext instanceIdentifier = controllerContext
- .toInstanceIdentifier("simple-nodes:userWithoutClass/foo");
- assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "userWithoutClass");
-
- instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:userWithoutClass/foo");
- assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "userWithoutClass");
-
- instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:user/foo/boo");
- assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "user");
-
- instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:user//boo");
- assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "user");
-
- }
-
- @Test
- public void testToInstanceIdentifierWithDoubleSlash() {
- InstanceIdentifierContext instanceIdentifier = controllerContext
- .toInstanceIdentifier("simple-nodes:food//nonalcoholic");
- assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "nonalcoholic");
-
- instanceIdentifier = controllerContext
- .toInstanceIdentifier("simple-nodes:userWithoutClass//");
- assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "userWithoutClass");
-
- instanceIdentifier = controllerContext
- .toInstanceIdentifier("simple-nodes:userWithoutClass///inner-container");
- assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "inner-container");
- }
-
- @Test
- public void testToInstanceIdentifierListWithNullKey() {
- assertThrows(RestconfDocumentedException.class,
- () -> controllerContext.toInstanceIdentifier("simple-nodes:user/null/boo"));
- }
-
- @Test
- public void testToInstanceIdentifierListWithMissingKey() {
- assertThrows(RestconfDocumentedException.class,
- () -> controllerContext.toInstanceIdentifier("simple-nodes:user/foo"));
- }
-
- @Test
- public void testToInstanceIdentifierContainer() {
- final InstanceIdentifierContext instanceIdentifier =
- controllerContext.toInstanceIdentifier("simple-nodes:users");
- assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "users");
- assertTrue(instanceIdentifier.getSchemaNode() instanceof ContainerSchemaNode);
- assertEquals(2, ((ContainerSchemaNode) instanceIdentifier.getSchemaNode()).getChildNodes().size());
- }
-
- @Test
- public void testToInstanceIdentifierChoice() {
- final InstanceIdentifierContext instanceIdentifier = controllerContext
- .toInstanceIdentifier("simple-nodes:food/nonalcoholic");
- assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "nonalcoholic");
- }
-
- @Test
- public void testToInstanceIdentifierChoiceException() {
- assertThrows(RestconfDocumentedException.class,
- () -> controllerContext.toInstanceIdentifier("simple-nodes:food/snack"));
- }
-
- @Test
- public void testToInstanceIdentifierCaseException() {
- assertThrows(RestconfDocumentedException.class,
- () -> controllerContext.toInstanceIdentifier("simple-nodes:food/sports-arena"));
- }
-
- @Test
- public void testToInstanceIdentifierChoiceCaseException() {
- assertThrows(RestconfDocumentedException.class,
- () -> controllerContext.toInstanceIdentifier("simple-nodes:food/snack/sports-arena"));
- }
-
- @Test
- public void testToInstanceIdentifierWithoutNode() {
- assertThrows(RestconfDocumentedException.class,
- () -> controllerContext.toInstanceIdentifier("simple-nodes"));
- }
-
- @Test
- public void testMountPointWithExternModul() {
- initSchemaService();
- final InstanceIdentifierContext instanceIdentifier = controllerContext
- .toInstanceIdentifier("simple-nodes:users/yang-ext:mount/test-interface2:class/student/name");
- assertEquals(
- "[(urn:ietf:params:xml:ns:yang:test-interface2?revision=2014-08-01)class, "
- + "(urn:ietf:params:xml:ns:yang:test-interface2?revision=2014-08-01)student, "
- + "(urn:ietf:params:xml:ns:yang:test-interface2?revision=2014-08-01)student"
- + "[{(urn:ietf:params:xml:ns:yang:test-interface2?revision=2014-08-01)name=name}]]",
- ImmutableList.copyOf(instanceIdentifier.getInstanceIdentifier().getPathArguments()).toString());
- }
-
- @Test
- public void testMountPointWithoutExternModul() {
- initSchemaService();
- final InstanceIdentifierContext instanceIdentifier = controllerContext
- .toInstanceIdentifier("simple-nodes:users/yang-ext:mount/");
- assertTrue(Iterables.isEmpty(instanceIdentifier.getInstanceIdentifier().getPathArguments()));
- }
-
- @Test
- public void testMountPointWithoutMountPointSchema() {
- assertThrows(RestconfDocumentedException.class,
- () -> controllerContext.toInstanceIdentifier("simple-nodes:users/yang-ext:mount/test-interface2:class"));
- }
-
- private void initSchemaService() {
- doReturn(Optional.of(FixedDOMSchemaService.of(mountSchemaContext))).when(mountInstance)
- .getService(DOMSchemaService.class);
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-import java.io.FileNotFoundException;
-import org.junit.BeforeClass;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
-
-public class XmlAndJsonToCnSnInstanceIdentifierTest extends YangAndXmlAndDataSchemaLoader {
-
- @BeforeClass
- public static void initialize() throws FileNotFoundException, ReactorException {
- dataLoad("/instanceidentifier/yang", 4, "instance-identifier-module", "cont");
- }
-
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-import java.io.FileNotFoundException;
-import org.junit.BeforeClass;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
-
-public class XmlAndJsonToCnSnLeafRefTest extends YangAndXmlAndDataSchemaLoader {
-
- final QName refContQName = QName.create("referenced:module", "2014-04-17", "cont");
- final QName refLf1QName = QName.create(this.refContQName, "lf1");
- final QName contQName = QName.create("leafref:module", "2014-04-17", "cont");
- final QName lf1QName = QName.create(this.contQName, "lf1");
- final QName lf2QName = QName.create(this.contQName, "lf2");
- final QName lf3QName = QName.create(this.contQName, "lf3");
-
- @BeforeClass
- public static void initialize() throws FileNotFoundException, ReactorException {
- dataLoad("/leafref/yang", 2, "leafref-module", "cont");
- }
-
-
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import java.io.FileNotFoundException;
-import java.util.Collection;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-
-public abstract class YangAndXmlAndDataSchemaLoader {
- protected static Collection<? extends Module> modules;
- protected static DataSchemaNode dataSchemaNode;
- protected static String searchedModuleName;
- protected static String searchedDataSchemaName;
- protected static String schemaNodePath;
-
- protected static void dataLoad(final String yangPath) throws FileNotFoundException {
- dataLoad(yangPath, 1, null, null);
- }
-
- protected static void dataLoad(final String yangPath, final int modulesNumber, final String moduleName,
- final String dataSchemaName) throws FileNotFoundException {
- modules = TestUtils.loadSchemaContext(yangPath).getModules();
- assertEquals(modulesNumber, modules.size());
- final Module module = TestUtils.resolveModule(moduleName, modules);
- searchedModuleName = module == null ? "" : module.getName();
- assertNotNull(module);
- dataSchemaNode = TestUtils.resolveDataSchemaNode(dataSchemaName, module);
- searchedDataSchemaName = dataSchemaNode == null ? "" : dataSchemaNode.getQName().getLocalName();
- assertNotNull(dataSchemaNode);
- schemaNodePath = searchedModuleName + ":" + searchedDataSchemaName;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2019 Red Hat, 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.controller.sal.restconf.impl.test.incubate;
-
-import com.google.inject.AbstractModule;
-import com.google.inject.Provides;
-import javax.annotation.PreDestroy;
-import javax.inject.Singleton;
-import org.opendaylight.mdsal.binding.api.DataBroker;
-import org.opendaylight.mdsal.binding.dom.adapter.test.AbstractBaseDataBrokerTest;
-import org.opendaylight.mdsal.binding.dom.adapter.test.AbstractConcurrentDataBrokerTest;
-import org.opendaylight.mdsal.dom.api.DOMDataBroker;
-import org.opendaylight.mdsal.dom.api.DOMMountPointService;
-import org.opendaylight.mdsal.dom.api.DOMNotificationPublishService;
-import org.opendaylight.mdsal.dom.api.DOMNotificationService;
-import org.opendaylight.mdsal.dom.api.DOMRpcService;
-import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.mdsal.dom.broker.DOMMountPointServiceImpl;
-import org.opendaylight.mdsal.dom.broker.DOMNotificationRouter;
-import org.opendaylight.mdsal.dom.broker.DOMRpcRouter;
-import org.opendaylight.mdsal.dom.spi.DOMNotificationSubscriptionListenerRegistry;
-import org.opendaylight.mdsal.dom.store.inmemory.InMemoryDOMDataStore;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContextProvider;
-
-/**
- * Guice Module which binds the mdsal (not controller) {@link DataBroker} & Co.
- * in-memory implementation suitable for tests.
- *
- * <p>This class is here only temporarily and it can and should be removed and
- * replaced when the equivalent will be offered by the mdsal project itself; see
- * <a href="https://jira.opendaylight.org/browse/MDSAL-418">MDSAL-418</a>. It is
- * also copy/pasted to org.opendaylight.restconf.nb.rfc8040.test.incubate.InMemoryMdsalModule.
- *
- * <p>BEWARE: Do *NOT* use this module in component tests or applications mixing
- * code requiring the old controller and the new mdsal {@link DataBroker} & Co.
- * APIs together - because this binds a *SEPARATE* {@link InMemoryDOMDataStore},
- * and doesn't delegate to controller's InMemoryDOMDataStore. This is just fine
- * for tests where all code under test already uses only the mdsal APIs.
- *
- * @author Michael Vorburger.ch
- */
-public class InMemoryMdsalModule extends AbstractModule {
-
- private static final int NOTIFICATION_SERVICE_QUEUE_DEPTH = 128;
-
- private final AbstractBaseDataBrokerTest dataBrokerTest;
- private final DOMNotificationRouter domNotificationRouter;
-
- public InMemoryMdsalModule() throws Exception {
- dataBrokerTest = new AbstractConcurrentDataBrokerTest(true) { // NOT AbstractDataBrokerTest
- };
- dataBrokerTest.setup();
-
- domNotificationRouter = DOMNotificationRouter.create(NOTIFICATION_SERVICE_QUEUE_DEPTH);
- }
-
- @Override
- protected void configure() {
- }
-
- @Provides
- @Singleton
- DataBroker getDataBroker() {
- return dataBrokerTest.getDataBroker();
- }
-
- @Provides
- @Singleton DOMDataBroker getDOMDataBroker() {
- return dataBrokerTest.getDomBroker();
- }
-
- @Provides
- @Singleton DOMNotificationRouter getDOMNotificationRouter() {
- return dataBrokerTest.getDataBrokerTestCustomizer().getDomNotificationRouter();
- }
-
- @Provides
- @Singleton DOMSchemaService getSchemaService() {
- return dataBrokerTest.getDataBrokerTestCustomizer().getSchemaService();
- }
-
- @Provides
- @Singleton EffectiveModelContextProvider getSchemaContextProvider() {
- DOMSchemaService schemaService = dataBrokerTest.getDataBrokerTestCustomizer().getSchemaService();
- if (schemaService instanceof EffectiveModelContextProvider) {
- return (EffectiveModelContextProvider) schemaService;
- }
- throw new IllegalStateException(
- "The schema service isn't a SchemaContextProvider, it's a " + schemaService.getClass());
- }
-
- @Provides
- @Singleton DOMMountPointService getDOMMountPoint() {
- return new DOMMountPointServiceImpl();
- }
-
- @Provides
- @Singleton DOMNotificationService getDOMNotificationService() {
- return domNotificationRouter;
- }
-
- @Provides
- @Singleton DOMNotificationPublishService getDOMNotificationPublishService() {
- return domNotificationRouter;
- }
-
- @Provides
- @Singleton DOMNotificationSubscriptionListenerRegistry getDOMNotificationSubscriptionListenerRegistry() {
- return domNotificationRouter;
- }
-
- @Provides
- @Singleton DOMRpcService getDOMRpcService(DOMSchemaService schemaService) {
- return DOMRpcRouter.newInstance(schemaService).getRpcService();
- }
-
- @PreDestroy
- public void close() {
- // TODO When moving this to mdsal, must close components to shut down Threads etc.
- // but cannot do this here (in netconf) yet, because we need to change AbstractBaseDataBrokerTest & Co..
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2018 Red Hat, 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.controller.sal.restconf.impl.test.incubate;
-
-import java.util.concurrent.ExecutionException;
-import javax.inject.Inject;
-import org.junit.Rule;
-import org.junit.Test;
-import org.opendaylight.infrautils.inject.guice.testutils.AnnotationsModule;
-import org.opendaylight.infrautils.inject.guice.testutils.GuiceRule;
-import org.opendaylight.mdsal.binding.api.DataBroker;
-
-/**
- * Test for {@link InMemoryMdsalModule}.
- *
- * <p>This will be removed when the local {@link InMemoryMdsalModule} incubating here
- * in netconf will be replaced by the one from mdsal.
- *
- * @author Michael Vorburger.ch
- */
-public class InMemoryMdsalModuleTest {
-
- public @Rule GuiceRule guice = new GuiceRule(InMemoryMdsalModule.class, AnnotationsModule.class);
-
- @Inject DataBroker dataBroker;
-
- @Test public void testDataBroker() throws InterruptedException, ExecutionException {
- dataBroker.newReadWriteTransaction().commit().get();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 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.controller.sal.restconf.impl.websockets.client;
-
-/**
- * Created by mbobak on 1/22/14.
- */
-public interface IClientMessageCallback {
-
- void onMessageReceived(Object message);
-}
+++ /dev/null
-/*
- * 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
- */
-package org.opendaylight.controller.sal.restconf.impl.websockets.client;
-
-import io.netty.bootstrap.Bootstrap;
-import io.netty.buffer.Unpooled;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.ChannelPipeline;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.SocketChannel;
-import io.netty.channel.socket.nio.NioSocketChannel;
-import io.netty.handler.codec.http.HttpClientCodec;
-import io.netty.handler.codec.http.HttpObjectAggregator;
-import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
-import io.netty.handler.codec.http.websocketx.PingWebSocketFrame;
-import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
-import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
-import io.netty.handler.codec.http.websocketx.WebSocketVersion;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.net.URI;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class WebSocketClient {
-
- private static final Logger LOG = LoggerFactory.getLogger(WebSocketClient.class);
-
- private final URI uri;
- private final Bootstrap bootstrap = new Bootstrap();
- private final WebSocketClientHandler clientHandler;
- private Channel clientChannel;
- private final EventLoopGroup group = new NioEventLoopGroup();
-
- public WebSocketClient(final URI uri, final IClientMessageCallback clientMessageCallback) {
- this.uri = uri;
- clientHandler = new WebSocketClientHandler(WebSocketClientHandshakerFactory.newHandshaker(uri,
- WebSocketVersion.V13, null, false, null), clientMessageCallback);
- // last null could be replaced with DefaultHttpHeaders
- initialize();
- }
-
- private void initialize() {
-
- String protocol = uri.getScheme();
- if (!"ws".equals(protocol)) {
- throw new IllegalArgumentException("Unsupported protocol: " + protocol);
- }
-
- bootstrap.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {
- @Override
- public void initChannel(final SocketChannel ch) throws Exception {
- ChannelPipeline pipeline = ch.pipeline();
- pipeline.addLast("http-codec", new HttpClientCodec());
- pipeline.addLast("aggregator", new HttpObjectAggregator(8192));
- pipeline.addLast("ws-handler", clientHandler);
- }
- });
- }
-
- public void connect() throws InterruptedException {
- LOG.info("WebSocket Client connecting");
- clientChannel = bootstrap.connect(uri.getHost(), uri.getPort()).sync().channel();
- clientHandler.handshakeFuture().sync();
- }
-
- public void writeAndFlush(final String message) {
- clientChannel.writeAndFlush(new TextWebSocketFrame(message));
- }
-
- public void writeAndFlush(final Object message) {
- clientChannel.writeAndFlush(message);
- }
-
- public void ping() {
- clientChannel.writeAndFlush(new PingWebSocketFrame(Unpooled.copiedBuffer(new byte[] { 1, 2, 3, 4, 5, 6 })));
- }
-
- public void close(final String reasonText) throws InterruptedException {
- CloseWebSocketFrame closeWebSocketFrame = new CloseWebSocketFrame(1000, reasonText);
- clientChannel.writeAndFlush(closeWebSocketFrame);
-
- // WebSocketClientHandler will close the connection when the server
- // responds to the CloseWebSocketFrame.
- clientChannel.closeFuture().sync();
- group.shutdownGracefully();
- }
-
- public static void main(final String[] args) throws Exception {
- URI uri;
- if (args.length > 0) {
- uri = new URI(args[0]);
- } else {
- uri = new URI("http://192.168.1.101:8181/opendaylight-inventory:nodes");
- }
- IClientMessageCallback messageCallback = new ClientMessageCallback();
- WebSocketClient webSocketClient = new WebSocketClient(uri, messageCallback);
- webSocketClient.connect();
-
- while (true) {
- BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
- String input = br.readLine();
- if (input.equals("q")) {
- LOG.info("Would you like to close stream? (Y = yes, empty = yes)\n");
- input = br.readLine();
- if (input.equals("yes") || input.isEmpty()) {
- webSocketClient.close("opendaylight-inventory:nodes");
- break;
- }
- }
- }
- }
-
- private static class ClientMessageCallback implements IClientMessageCallback {
- @Override
- public void onMessageReceived(final Object message) {
- if (message instanceof TextWebSocketFrame) {
- LOG.info("received message {}" + ((TextWebSocketFrame) message).text());
- }
- }
- }
-
-}
+++ /dev/null
-/*
- * 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
- */
-package org.opendaylight.controller.sal.restconf.impl.websockets.client;
-
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelPromise;
-import io.netty.channel.SimpleChannelInboundHandler;
-import io.netty.handler.codec.http.FullHttpResponse;
-import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
-import io.netty.handler.codec.http.websocketx.PongWebSocketFrame;
-import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;
-import io.netty.handler.codec.http.websocketx.WebSocketFrame;
-import io.netty.util.CharsetUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class WebSocketClientHandler extends SimpleChannelInboundHandler<Object> {
-
- private static final Logger LOG = LoggerFactory.getLogger(WebSocketClientHandler.class.toString());
- private final WebSocketClientHandshaker handshaker;
- private ChannelPromise handshakeFuture;
- private final IClientMessageCallback messageListener;
-
- public WebSocketClientHandler(final WebSocketClientHandshaker handshaker, final IClientMessageCallback listener) {
- this.handshaker = handshaker;
- this.messageListener = listener;
- }
-
- public ChannelFuture handshakeFuture() {
- return handshakeFuture;
- }
-
- @Override
- public void handlerAdded(final ChannelHandlerContext ctx) throws Exception {
- handshakeFuture = ctx.newPromise();
- }
-
- @Override
- public void channelActive(final ChannelHandlerContext ctx) throws Exception {
- handshaker.handshake(ctx.channel());
- }
-
- @Override
- public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
- LOG.info("WebSocket Client disconnected!");
- }
-
- @Override
- public void channelRead0(final ChannelHandlerContext ctx, final Object msg) throws Exception {
- Channel ch = ctx.channel();
- if (!handshaker.isHandshakeComplete()) {
- handshaker.finishHandshake(ch, (FullHttpResponse) msg);
- LOG.info("WebSocket Client connected!");
- handshakeFuture.setSuccess();
- return;
- }
-
- if (msg instanceof FullHttpResponse) {
- FullHttpResponse response = (FullHttpResponse) msg;
- throw new Exception("Unexpected FullHttpResponse (getStatus=" + response.status() + ", content="
- + response.content().toString(CharsetUtil.UTF_8) + ')');
- }
-
- messageListener.onMessageReceived(msg);
- WebSocketFrame frame = (WebSocketFrame) msg;
-
- if (frame instanceof PongWebSocketFrame) {
- LOG.info("WebSocket Client received pong");
- } else if (frame instanceof CloseWebSocketFrame) {
- LOG.info("WebSocket Client received closing");
- ch.close();
- }
- }
-
- @Override
- public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) throws Exception {
- LOG.info("Cause: {} .", cause.toString());
-
- if (!handshakeFuture.isDone()) {
- handshakeFuture.setFailure(cause);
- }
-
- ctx.close();
- }
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.websockets.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-
-import java.io.FileNotFoundException;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.BeforeClass;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
-import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeJsonBodyWriter;
-import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeXmlBodyWriter;
-import org.opendaylight.netconf.sal.rest.impl.RestconfDocumentedExceptionMapper;
-import org.opendaylight.netconf.sal.rest.impl.XmlNormalizedNodeBodyReader;
-import org.opendaylight.netconf.sal.restconf.impl.BrokerFacade;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.netconf.sal.restconf.impl.RestconfImpl;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-public class RestStreamTest extends JerseyTest {
-
- private static EffectiveModelContext schemaContextYangsIetf;
-
- private BrokerFacade brokerFacade;
- private RestconfImpl restconfImpl;
-
- @BeforeClass
- public static void init() throws FileNotFoundException, ReactorException {
- schemaContextYangsIetf = TestUtils.loadSchemaContext("/full-versions/yangs");
- }
-
- @Override
- protected Application configure() {
- /* enable/disable Jersey logs to console */
- // enable(TestProperties.LOG_TRAFFIC);
- // enable(TestProperties.DUMP_ENTITY);
- // enable(TestProperties.RECORD_LOG_LEVEL);
- // set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
-
- final ControllerContext controllerContext = TestRestconfUtils.newControllerContext(schemaContextYangsIetf);
- brokerFacade = mock(BrokerFacade.class);
- restconfImpl = RestconfImpl.newInstance(brokerFacade, controllerContext);
-
- ResourceConfig resourceConfig = new ResourceConfig();
- resourceConfig = resourceConfig.registerInstances(restconfImpl, new NormalizedNodeJsonBodyWriter(),
- new NormalizedNodeXmlBodyWriter(), new XmlNormalizedNodeBodyReader(controllerContext),
- new JsonNormalizedNodeBodyReader(controllerContext),
- new RestconfDocumentedExceptionMapper(controllerContext));
- return resourceConfig;
- }
-
- @Test
- @Ignore // Sporadic failures where jersey does not correctly pass post data to XmlNormalizedNodeBodyReader.readFrom
- public void testCallRpcCallGet() throws UnsupportedEncodingException, InterruptedException {
- createAndSubscribe(null);
- }
-
- @Test
- @Ignore // Sporadic failures where jersey does not correctly pass post data to XmlNormalizedNodeBodyReader.readFrom
- public void testCallRpcCallGetLeaves() throws UnsupportedEncodingException, InterruptedException {
- createAndSubscribe("odl-leaf-nodes-only", "true");
- }
-
- private void createAndSubscribe(final String queryParamName, final Object... values)
- throws UnsupportedEncodingException, InterruptedException {
- String uri = "/operations/sal-remote:create-data-change-event-subscription";
- String rpcInput = getRpcInput();
- final Response responseWithStreamName = post(uri, MediaType.APPLICATION_XML, rpcInput);
- final Document xmlResponse = responseWithStreamName.readEntity(Document.class);
- assertNotNull(xmlResponse);
- final Element outputElement = xmlResponse.getDocumentElement();
- assertEquals("output",outputElement.getLocalName());
-
- final Node streamNameElement = outputElement.getFirstChild();
- assertEquals("stream-name",streamNameElement.getLocalName());
- assertEquals("data-change-event-subscription/ietf-interfaces:interfaces/ietf-interfaces:interface/eth0/"
- + "datastore=CONFIGURATION/scope=BASE",streamNameElement.getTextContent());
-
- uri = "/streams/stream/data-change-event-subscription/ietf-interfaces:interfaces/ietf-interfaces:interface/"
- + "eth0/datastore=CONFIGURATION/scope=BASE";
- final Response responseWithRedirectionUri = get(uri, MediaType.APPLICATION_XML, null);
- final URI websocketServerUri = responseWithRedirectionUri.getLocation();
- assertNotNull(websocketServerUri);
- assertTrue(websocketServerUri.toString().matches(".*ws://localhost:[\\d]+/data-change-event-subscription/"
- + "ietf-interfaces:interfaces/ietf-interfaces:interface/eth0.*"));
- }
-
- private Response post(final String uri, final String mediaType, final String data) {
- return target(uri).request(mediaType).post(Entity.entity(data, mediaType));
- }
-
- private Response get(final String uri, final String mediaType, final String queryParam, final Object... values) {
- if (queryParam != null) {
- return target(uri).queryParam(queryParam, values).request(mediaType).get();
- } else {
- return target(uri).request(mediaType).get();
- }
- }
-
- private static String getRpcInput() {
- final StringBuilder sb = new StringBuilder();
- sb.append("<input xmlns=\"urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote\">");
- sb.append("<path xmlns:int=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\">/"
- + "int:interfaces/int:interface[int:name='eth0']</path>");
- sb.append("</input>");
- return sb.toString();
- }
-
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.xml.to.cnsn.test;
-
-
-public class XmlAugmentedElementToCnSnTest {
-
-}
+++ /dev/null
-/*
- * 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.controller.sal.restconf.impl.xml.to.cnsn.test;
-
-import java.io.FileNotFoundException;
-import org.junit.BeforeClass;
-import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
-
-public class XmlToCnSnTest extends YangAndXmlAndDataSchemaLoader {
-
- @BeforeClass
- public static void initialize() throws FileNotFoundException, ReactorException {
- dataLoad("/xml-to-cnsn/leafref");
- }
-
-}
+++ /dev/null
-/*
- * 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.sal.rest.impl;
-
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import com.google.common.collect.Sets;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Optional;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-
-@RunWith(MockitoJUnitRunner.StrictStubs.class)
-public class DepthAwareNormalizedNodeWriterTest {
-
- @Mock
- private NormalizedNodeStreamWriter writer;
- @Mock
- private ContainerNode containerNodeData;
- @Mock
- private MapNode mapNodeData;
- @Mock
- private MapEntryNode mapEntryNodeData;
- @Mock
- private LeafSetNode<String> leafSetNodeData;
- @Mock
- private LeafSetEntryNode<String> leafSetEntryNodeData;
- @Mock
- private LeafNode<String> keyLeafNodeData;
- @Mock
- private LeafNode<String> anotherLeafNodeData;
-
- private NodeIdentifier containerNodeIdentifier;
- private NodeIdentifier mapNodeIdentifier;
- private NodeIdentifierWithPredicates mapEntryNodeIdentifier;
- private NodeIdentifier leafSetNodeIdentifier;
- private NodeWithValue<String> leafSetEntryNodeIdentifier;
- private NodeIdentifier keyLeafNodeIdentifier;
- private NodeIdentifier anotherLeafNodeIdentifier;
-
- private Collection<DataContainerChild> containerNodeValue;
- private Collection<MapEntryNode> mapNodeValue;
- private Collection<DataContainerChild> mapEntryNodeValue;
- private Collection<LeafSetEntryNode<String>> leafSetNodeValue;
- private String leafSetEntryNodeValue;
- private String keyLeafNodeValue;
- private String anotherLeafNodeValue;
-
- @Before
- public void setUp() {
- // identifiers
- containerNodeIdentifier = NodeIdentifier.create(QName.create("namespace", "container"));
- when(containerNodeData.getIdentifier()).thenReturn(containerNodeIdentifier);
-
- mapNodeIdentifier = NodeIdentifier.create(QName.create("namespace", "list"));
- when(mapNodeData.getIdentifier()).thenReturn(mapNodeIdentifier);
-
- final QName leafSetEntryNodeQName = QName.create("namespace", "leaf-set-entry");
- leafSetEntryNodeValue = "leaf-set-value";
- leafSetEntryNodeIdentifier = new NodeWithValue<>(leafSetEntryNodeQName, leafSetEntryNodeValue);
- when(leafSetEntryNodeData.getIdentifier()).thenReturn(leafSetEntryNodeIdentifier);
-
- leafSetNodeIdentifier = NodeIdentifier.create(QName.create("namespace", "leaf-set"));
- when(leafSetNodeData.getIdentifier()).thenReturn(leafSetNodeIdentifier);
-
- final QName mapEntryNodeKey = QName.create("namespace", "key-field");
- keyLeafNodeIdentifier = NodeIdentifier.create(mapEntryNodeKey);
- keyLeafNodeValue = "key-value";
-
- mapEntryNodeIdentifier = NodeIdentifierWithPredicates.of(
- QName.create("namespace", "list-entry"), mapEntryNodeKey, keyLeafNodeValue);
- when(mapEntryNodeData.getIdentifier()).thenReturn(mapEntryNodeIdentifier);
- when(mapEntryNodeData.findChildByArg(keyLeafNodeIdentifier)).thenReturn(Optional.of(keyLeafNodeData));
-
- when(keyLeafNodeData.body()).thenReturn(keyLeafNodeValue);
- when(keyLeafNodeData.getIdentifier()).thenReturn(keyLeafNodeIdentifier);
-
- anotherLeafNodeIdentifier = NodeIdentifier.create(QName.create("namespace", "another-field"));
- anotherLeafNodeValue = "another-value";
-
- when(anotherLeafNodeData.body()).thenReturn(anotherLeafNodeValue);
- when(anotherLeafNodeData.getIdentifier()).thenReturn(anotherLeafNodeIdentifier);
-
- // values
- when(leafSetEntryNodeData.body()).thenReturn(leafSetEntryNodeValue);
-
- leafSetNodeValue = Collections.singletonList(leafSetEntryNodeData);
- when(leafSetNodeData.body()).thenReturn(leafSetNodeValue);
-
- containerNodeValue = Collections.singleton(leafSetNodeData);
- when(containerNodeData.body()).thenReturn(containerNodeValue);
-
- mapEntryNodeValue = Sets.newHashSet(keyLeafNodeData, anotherLeafNodeData);
- when(mapEntryNodeData.body()).thenReturn(mapEntryNodeValue);
-
- mapNodeValue = Collections.singleton(mapEntryNodeData);
- when(mapNodeData.body()).thenReturn(mapNodeValue);
- }
-
- /**
- * Test write {@link ContainerNode} with children but write data only to depth 1 (children will not be written).
- */
- @Test
- public void writeContainerWithoutChildrenTest() throws Exception {
- final DepthAwareNormalizedNodeWriter depthWriter = DepthAwareNormalizedNodeWriter.forStreamWriter(writer, 1);
-
- depthWriter.write(containerNodeData);
-
- final InOrder inOrder = inOrder(writer);
- inOrder.verify(writer, times(1)).startContainerNode(containerNodeIdentifier, containerNodeValue.size());
- inOrder.verify(writer, times(1)).endNode();
- verifyNoMoreInteractions(writer);
- }
-
- /**
- * Test write {@link ContainerNode} with children and write also all its children.
- */
- @Test
- public void writeContainerWithChildrenTest() throws Exception {
- final DepthAwareNormalizedNodeWriter depthWriter = DepthAwareNormalizedNodeWriter.forStreamWriter(
- writer, Integer.MAX_VALUE);
-
- depthWriter.write(containerNodeData);
-
- final InOrder inOrder = inOrder(writer);
- inOrder.verify(writer, times(1)).startContainerNode(containerNodeIdentifier, containerNodeValue.size());
- inOrder.verify(writer, times(1)).startLeafSet(leafSetNodeIdentifier, leafSetNodeValue.size());
- inOrder.verify(writer, times(1)).startLeafSetEntryNode(leafSetEntryNodeIdentifier);
- inOrder.verify(writer, times(1)).scalarValue(leafSetEntryNodeValue);
- inOrder.verify(writer, times(3)).endNode();
- verifyNoMoreInteractions(writer);
- }
-
- /**
- * Test write with {@link MapNode} with children but write data only to depth 1 (children will not be written).
- */
- @Test
- public void writeMapNodeWithoutChildrenTest() throws Exception {
- final DepthAwareNormalizedNodeWriter depthWriter = DepthAwareNormalizedNodeWriter.forStreamWriter(writer, 1);
-
- depthWriter.write(mapNodeData);
-
- final InOrder inOrder = inOrder(writer);
- inOrder.verify(writer, times(1)).startMapNode(mapNodeIdentifier, mapNodeValue.size());
- inOrder.verify(writer, times(1)).startMapEntryNode(mapEntryNodeIdentifier, mapEntryNodeValue.size());
- inOrder.verify(writer, times(1)).startLeafNode(keyLeafNodeIdentifier);
- inOrder.verify(writer, times(1)).scalarValue(keyLeafNodeValue);
- inOrder.verify(writer, times(3)).endNode();
- verifyNoMoreInteractions(writer);
- }
-
- /**
- * Test write {@link MapNode} with children and write also all its children.
- * FIXME
- * Although ordered writer is used leaves are not written in expected order.
- *
- */
- @Ignore
- @Test
- public void writeMapNodeWithChildrenTest() throws Exception {
- final DepthAwareNormalizedNodeWriter depthWriter = DepthAwareNormalizedNodeWriter.forStreamWriter(
- writer, Integer.MAX_VALUE);
-
- depthWriter.write(mapNodeData);
-
- final InOrder inOrder = inOrder(writer);
- inOrder.verify(writer, times(1)).startMapNode(mapNodeIdentifier, mapNodeValue.size());
- inOrder.verify(writer, times(1)).startMapEntryNode(mapEntryNodeIdentifier, mapEntryNodeValue.size());
- inOrder.verify(writer, times(1)).startLeafNode(keyLeafNodeIdentifier);
- inOrder.verify(writer, times(1)).scalarValue(keyLeafNodeValue);
- inOrder.verify(writer, times(1)).endNode();
- inOrder.verify(writer, times(1)).startLeafNode(keyLeafNodeIdentifier);
- inOrder.verify(writer, times(1)).scalarValue(keyLeafNodeValue);
- inOrder.verify(writer, times(1)).endNode();
-
- // FIXME this assertion is not working because leaves are not written in expected order
- inOrder.verify(writer, times(1)).startLeafNode(anotherLeafNodeIdentifier);
- inOrder.verify(writer, times(1)).scalarValue(anotherLeafNodeValue);
- inOrder.verify(writer, times(3)).endNode();
- verifyNoMoreInteractions(writer);
- }
-
- /**
- * Test write with {@link LeafSetNode} with depth 1 (children will not be written).
- */
- @Test
- public void writeLeafSetNodeWithoutChildrenTest() throws Exception {
- final DepthAwareNormalizedNodeWriter depthWriter = DepthAwareNormalizedNodeWriter.forStreamWriter(
- writer, 1);
-
- depthWriter.write(leafSetNodeData);
-
- final InOrder inOrder = inOrder(writer);
- inOrder.verify(writer, times(1)).startLeafSet(leafSetNodeIdentifier, leafSetNodeValue.size());
- inOrder.verify(writer, times(1)).endNode();
- verifyNoMoreInteractions(writer);
- }
-
- /**
- * Test write with {@link LeafSetNode} when all its children will be written.
- */
- @Test
- public void writeLeafSetNodeWithChildrenTest() throws Exception {
- final DepthAwareNormalizedNodeWriter depthWriter = DepthAwareNormalizedNodeWriter.forStreamWriter(
- writer, Integer.MAX_VALUE);
-
- depthWriter.write(leafSetNodeData);
-
- final InOrder inOrder = inOrder(writer);
- inOrder.verify(writer, times(1)).startLeafSet(leafSetNodeIdentifier, leafSetNodeValue.size());
- inOrder.verify(writer, times(1)).startLeafSetEntryNode(leafSetEntryNodeIdentifier);
- inOrder.verify(writer, times(1)).scalarValue(leafSetEntryNodeValue);
- inOrder.verify(writer, times(2)).endNode();
- verifyNoMoreInteractions(writer);
- }
-
- /**
- * Test write with {@link LeafSetEntryNode}.
- */
- @Test
- public void writeLeafSetEntryNodeTest() throws Exception {
- final DepthAwareNormalizedNodeWriter depthWriter = DepthAwareNormalizedNodeWriter.forStreamWriter(
- writer, Integer.MAX_VALUE);
-
- depthWriter.write(leafSetEntryNodeData);
-
- final InOrder inOrder = inOrder(writer);
- inOrder.verify(writer, times(1)).startLeafSetEntryNode(leafSetEntryNodeIdentifier);
- inOrder.verify(writer, times(1)).scalarValue(leafSetEntryNodeValue);
- inOrder.verify(writer, times(1)).endNode();
- verifyNoMoreInteractions(writer);
- }
-
- /**
- * Test write with {@link MapEntryNode} unordered to depth 1 to write only keys.
- */
- @Test
- public void writeMapEntryNodeUnorderedOnlyKeysTest() throws Exception {
- final DepthAwareNormalizedNodeWriter depthWriter = DepthAwareNormalizedNodeWriter.forStreamWriter(
- writer, false, 1);
-
- depthWriter.write(mapEntryNodeData);
-
- final InOrder inOrder = inOrder(writer);
- inOrder.verify(writer, times(1)).startMapEntryNode(mapEntryNodeIdentifier, mapEntryNodeValue.size());
- // write only the key
- inOrder.verify(writer, times(1)).startLeafNode(keyLeafNodeIdentifier);
- inOrder.verify(writer, times(1)).scalarValue(keyLeafNodeValue);
- inOrder.verify(writer, times(2)).endNode();
- verifyNoMoreInteractions(writer);
- }
-
- /**
- * Test write with {@link MapEntryNode} unordered with full depth.
- */
- @Test
- public void writeMapEntryNodeUnorderedTest() throws Exception {
- final DepthAwareNormalizedNodeWriter depthWriter = DepthAwareNormalizedNodeWriter.forStreamWriter(
- writer, false, Integer.MAX_VALUE);
-
- depthWriter.write(mapEntryNodeData);
-
- // unordered
- verify(writer, times(1)).startMapEntryNode(mapEntryNodeIdentifier, mapEntryNodeValue.size());
- verify(writer, times(1)).startLeafNode(keyLeafNodeIdentifier);
- verify(writer, times(1)).scalarValue(keyLeafNodeValue);
- verify(writer, times(1)).startLeafNode(anotherLeafNodeIdentifier);
- verify(writer, times(1)).scalarValue(anotherLeafNodeValue);
- verify(writer, times(3)).endNode();
- verifyNoMoreInteractions(writer);
- }
-
- /**
- * Test write with {@link MapEntryNode} ordered with depth 1 (children will not be written).
- */
- @Test
- public void writeMapEntryNodeOrderedWithoutChildrenTest() throws Exception {
- final DepthAwareNormalizedNodeWriter depthWriter = DepthAwareNormalizedNodeWriter.forStreamWriter(
- writer, true, 1);
-
- depthWriter.write(mapEntryNodeData);
-
- final InOrder inOrder = inOrder(writer);
- inOrder.verify(writer, times(1)).startMapEntryNode(mapEntryNodeIdentifier, mapEntryNodeValue.size());
- inOrder.verify(writer, times(1)).startLeafNode(keyLeafNodeIdentifier);
- inOrder.verify(writer, times(1)).scalarValue(keyLeafNodeValue);
- inOrder.verify(writer, times(2)).endNode();
- verifyNoMoreInteractions(writer);
- }
-
- /**
- * Test write with {@link MapEntryNode} ordered and write also all its children.
- * FIXME
- * Although ordered writer is used leaves are not written in expected order.
- *
- */
- @Ignore
- @Test
- public void writeMapEntryNodeOrderedTest() throws Exception {
- final DepthAwareNormalizedNodeWriter depthWriter = DepthAwareNormalizedNodeWriter.forStreamWriter(
- writer, true, Integer.MAX_VALUE);
-
- depthWriter.write(mapEntryNodeData);
-
- final InOrder inOrder = inOrder(writer);
- inOrder.verify(writer, times(1)).startMapEntryNode(mapEntryNodeIdentifier, mapEntryNodeValue.size());
- inOrder.verify(writer, times(2)).startLeafNode(keyLeafNodeIdentifier);
- inOrder.verify(writer, times(2)).scalarValue(keyLeafNodeValue);
- inOrder.verify(writer, times(1)).endNode();
- // FIXME this assertion is not working because leaves are not written in expected order
- inOrder.verify(writer, times(1)).startLeafNode(anotherLeafNodeIdentifier);
- inOrder.verify(writer, times(2)).scalarValue(anotherLeafNodeValue);
- inOrder.verify(writer, times(2)).endNode();
- verifyNoMoreInteractions(writer);
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.sal.restconf.impl;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
-import java.io.FileNotFoundException;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.netconf.sal.restconf.impl.RestCodec.InstanceIdentifierCodecImpl;
-import org.opendaylight.restconf.common.util.IdentityValuesDTO;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
-
-public class InstanceIdentifierCodecImplTest {
- private static EffectiveModelContext schemaContext;
-
- private InstanceIdentifierCodecImpl instanceIdentifierDTO;
- private YangInstanceIdentifier instanceIdentifierBadNamespace;
- private YangInstanceIdentifier instanceIdentifierOKList;
- private YangInstanceIdentifier instanceIdentifierOKLeafList;
-
- @BeforeClass
- public static void init() throws FileNotFoundException {
- schemaContext = YangParserTestUtils.parseYangFiles(
- TestRestconfUtils.loadFiles("/restconf/parser/deserializer"));
- }
-
- @Before
- public void setUp() throws Exception {
- ControllerContext controllerContext = TestRestconfUtils.newControllerContext(schemaContext);
-
- this.instanceIdentifierDTO = new InstanceIdentifierCodecImpl(null, controllerContext);
-
- final QName baseQName = QName.create("deserializer:test", "2016-06-06", "deserializer-test");
- final QName contA = QName.create(baseQName, "contA");
- final QName leafList = QName.create(baseQName, "leaf-list-A");
-
- this.instanceIdentifierOKLeafList = YangInstanceIdentifier.builder()
- .node(contA)
- .node(new YangInstanceIdentifier.NodeWithValue<>(leafList, "instance"))
- .build();
-
- this.instanceIdentifierOKList = YangInstanceIdentifier.builder()
- .node(NodeIdentifierWithPredicates.of(
- QName.create(baseQName, "list-one-key"),
- QName.create(QName.create(baseQName, "list-one-key"), "name"), "value"))
- .build();
-
- this.instanceIdentifierBadNamespace = YangInstanceIdentifier.builder()
- .nodeWithKey(QName.create("nonexistent:module", "2016-10-17", "nonexistent-1"),
- QName.create("nonexistent:module", "2016-10-17", "nonexistent"),
- "value")
- .build();
- }
-
- @Test
- public void testSerializeDeserializeList() throws Exception {
- final IdentityValuesDTO valuesDTO =
- this.instanceIdentifierDTO.serialize(this.instanceIdentifierOKList);
-
- final YangInstanceIdentifier deserializedIdentifier =
- this.instanceIdentifierDTO.deserialize(valuesDTO);
- assertEquals(this.instanceIdentifierOKList, deserializedIdentifier);
- }
-
- @Test
- public void testSerializeDeserializeLeafList() throws Exception {
- final IdentityValuesDTO valuesDTO =
- this.instanceIdentifierDTO.serialize(this.instanceIdentifierOKLeafList);
-
- final YangInstanceIdentifier deserializedIdentifier =
- this.instanceIdentifierDTO.deserialize(valuesDTO);
- assertEquals(this.instanceIdentifierOKLeafList, deserializedIdentifier);
- }
-
- @Test
- public void testSerializeDeserializeBadModuleNamespace() throws Exception {
- final IdentityValuesDTO valuesDTO =
- this.instanceIdentifierDTO.serialize(this.instanceIdentifierBadNamespace);
- assertEquals("nonexistent-1", valuesDTO.getValuesWithNamespaces().get(0).getValue());
- assertEquals("nonexistent:module", valuesDTO.getValuesWithNamespaces().get(0).getNamespace());
-
- final YangInstanceIdentifier deserializedIdentifier =
- this.instanceIdentifierDTO.deserialize(valuesDTO);
- assertNull(deserializedIdentifier);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 Red Hat, 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.sal.streams.listeners;
-
-import static java.time.Instant.EPOCH;
-
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.Optional;
-import org.json.JSONObject;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.mdsal.binding.api.DataBroker;
-import org.opendaylight.mdsal.binding.api.WriteTransaction;
-import org.opendaylight.mdsal.binding.dom.adapter.test.AbstractConcurrentDataBrokerTest;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataBroker;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeService;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.yang.gen.v1.instance.identifier.patch.module.rev151121.PatchCont;
-import org.opendaylight.yang.gen.v1.instance.identifier.patch.module.rev151121.patch.cont.MyList1;
-import org.opendaylight.yang.gen.v1.instance.identifier.patch.module.rev151121.patch.cont.MyList1Builder;
-import org.opendaylight.yang.gen.v1.instance.identifier.patch.module.rev151121.patch.cont.MyList1Key;
-import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
-import org.skyscreamer.jsonassert.JSONAssert;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ListenerAdapterTest extends AbstractConcurrentDataBrokerTest {
- private static final Logger LOG = LoggerFactory.getLogger(ListenerAdapterTest.class);
-
- private static final String JSON_NOTIF_LEAVES_CREATE = "/listener-adapter-test/notif-leaves-create.json";
- private static final String JSON_NOTIF_LEAVES_UPDATE = "/listener-adapter-test/notif-leaves-update.json";
- private static final String JSON_NOTIF_LEAVES_DEL = "/listener-adapter-test/notif-leaves-del.json";
- private static final String JSON_NOTIF_CREATE = "/listener-adapter-test/notif-create.json";
- private static final String JSON_NOTIF_UPDATE = "/listener-adapter-test/notif-update.json";
- private static final String JSON_NOTIF_DEL = "/listener-adapter-test/notif-del.json";
- private static final String JSON_NOTIF_WITHOUT_DATA_CREATE =
- "/listener-adapter-test/notif-without-data-create.json";
- private static final String JSON_NOTIF_WITHOUT_DATA_UPDATE =
- "/listener-adapter-test/notif-without-data-update.json";
- private static final String JSON_NOTIF_WITHOUT_DATA_DELETE =
- "/listener-adapter-test/notif-without-data-del.json";
-
-
- private static final YangInstanceIdentifier PATCH_CONT_YIID =
- YangInstanceIdentifier.create(new YangInstanceIdentifier.NodeIdentifier(PatchCont.QNAME));
-
- private static EffectiveModelContext schemaContext;
-
- private DataBroker dataBroker;
- private DOMDataBroker domDataBroker;
- private ControllerContext controllerContext;
-
- @BeforeClass
- public static void init() {
- schemaContext = YangParserTestUtils.parseYangResource(
- "/instanceidentifier/yang/instance-identifier-patch-module.yang");
- }
-
- @Before
- public void setUp() throws Exception {
- dataBroker = getDataBroker();
- domDataBroker = getDomBroker();
- controllerContext = TestRestconfUtils.newControllerContext(schemaContext);
- }
-
- class ListenerAdapterTester extends ListenerAdapter {
-
- private String lastNotification = null;
-
- ListenerAdapterTester(final YangInstanceIdentifier path, final String streamName,
- final NotificationOutputTypeGrouping.NotificationOutputType outputType,
- final boolean leafNodesOnly, final boolean skipNotificationData) {
- super(path, streamName, outputType, controllerContext);
- setQueryParams(EPOCH, Optional.empty(), Optional.empty(), leafNodesOnly, skipNotificationData);
- }
-
- @Override
- protected void post(final Event event) {
- this.lastNotification = event.getData();
- }
-
- public void assertGot(final String json) throws Exception {
- long start = System.currentTimeMillis();
- while (true) {
- if (lastNotification != null) {
- break;
- }
- if (System.currentTimeMillis() - start > 1000) {
- throw new Exception("TIMED OUT waiting for notification with " + json);
- }
- Thread.currentThread();
- Thread.sleep(200);
- }
- LOG.debug("Comparing {} {}", json, lastNotification);
- JSONAssert.assertEquals(json, withFakeDate(lastNotification), false);
- this.lastNotification = null;
- }
- }
-
- static String withFakeDate(final String in) {
- JSONObject doc = new JSONObject(in);
- JSONObject notification = doc.getJSONObject("notification");
- if (notification == null) {
- return in;
- }
- notification.put("eventTime", "someDate");
- return doc.toString();
- }
-
- private String getNotifJson(final String path) throws IOException, URISyntaxException {
- URL url = getClass().getResource(path);
- byte[] bytes = Files.readAllBytes(Paths.get(url.toURI()));
- return withFakeDate(new String(bytes, StandardCharsets.UTF_8));
- }
-
- @Test
- public void testJsonNotifsLeaves() throws Exception {
- ListenerAdapterTester adapter = new ListenerAdapterTester(PATCH_CONT_YIID, "Casey",
- NotificationOutputTypeGrouping.NotificationOutputType.JSON, true, false);
- DOMDataTreeChangeService changeService = domDataBroker.getExtensions()
- .getInstance(DOMDataTreeChangeService.class);
- DOMDataTreeIdentifier root = new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, PATCH_CONT_YIID);
- changeService.registerDataTreeChangeListener(root, adapter);
-
- WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
- MyList1Builder builder = new MyList1Builder().setMyLeaf11("Jed").setName("Althea");
- InstanceIdentifier<MyList1> iid = InstanceIdentifier.create(PatchCont.class)
- .child(MyList1.class, new MyList1Key("Althea"));
- writeTransaction.mergeParentStructurePut(LogicalDatastoreType.CONFIGURATION, iid, builder.build());
- writeTransaction.commit();
- adapter.assertGot(getNotifJson(JSON_NOTIF_LEAVES_CREATE));
-
- writeTransaction = dataBroker.newWriteOnlyTransaction();
- builder = new MyList1Builder().withKey(new MyList1Key("Althea")).setMyLeaf12("Bertha");
- writeTransaction.mergeParentStructureMerge(LogicalDatastoreType.CONFIGURATION, iid, builder.build());
- writeTransaction.commit();
- adapter.assertGot(getNotifJson(JSON_NOTIF_LEAVES_UPDATE));
-
- writeTransaction = dataBroker.newWriteOnlyTransaction();
- writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, iid);
- writeTransaction.commit();
- adapter.assertGot(getNotifJson(JSON_NOTIF_LEAVES_DEL));
- }
-
- @Test
- public void testJsonNotifs() throws Exception {
- ListenerAdapterTester adapter = new ListenerAdapterTester(PATCH_CONT_YIID, "Casey",
- NotificationOutputTypeGrouping.NotificationOutputType.JSON, false, false);
- DOMDataTreeChangeService changeService = domDataBroker.getExtensions()
- .getInstance(DOMDataTreeChangeService.class);
- DOMDataTreeIdentifier root = new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, PATCH_CONT_YIID);
- changeService.registerDataTreeChangeListener(root, adapter);
-
- WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
- MyList1Builder builder = new MyList1Builder().setMyLeaf11("Jed").setName("Althea");
- InstanceIdentifier<MyList1> iid = InstanceIdentifier.create(PatchCont.class)
- .child(MyList1.class, new MyList1Key("Althea"));
- writeTransaction.mergeParentStructurePut(LogicalDatastoreType.CONFIGURATION, iid, builder.build());
- writeTransaction.commit();
- adapter.assertGot(getNotifJson(JSON_NOTIF_CREATE));
-
- writeTransaction = dataBroker.newWriteOnlyTransaction();
- builder = new MyList1Builder().withKey(new MyList1Key("Althea")).setMyLeaf12("Bertha");
- writeTransaction.mergeParentStructureMerge(LogicalDatastoreType.CONFIGURATION, iid, builder.build());
- writeTransaction.commit();
- adapter.assertGot(getNotifJson(JSON_NOTIF_UPDATE));
-
- writeTransaction = dataBroker.newWriteOnlyTransaction();
- writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, iid);
- writeTransaction.commit();
- adapter.assertGot(getNotifJson(JSON_NOTIF_DEL));
- }
-
- @Test
- public void testJsonNotifsWithoutData() throws Exception {
- ListenerAdapterTester adapter = new ListenerAdapterTester(PATCH_CONT_YIID, "Casey",
- NotificationOutputTypeGrouping.NotificationOutputType.JSON, false, true);
- DOMDataTreeChangeService changeService = domDataBroker.getExtensions()
- .getInstance(DOMDataTreeChangeService.class);
- DOMDataTreeIdentifier root = new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, PATCH_CONT_YIID);
- changeService.registerDataTreeChangeListener(root, adapter);
-
- WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
- MyList1Builder builder = new MyList1Builder().setMyLeaf11("Jed").setName("Althea");
- InstanceIdentifier<MyList1> iid = InstanceIdentifier.create(PatchCont.class)
- .child(MyList1.class, new MyList1Key("Althea"));
- writeTransaction.mergeParentStructurePut(LogicalDatastoreType.CONFIGURATION, iid, builder.build());
- writeTransaction.commit();
- adapter.assertGot(getNotifJson(JSON_NOTIF_WITHOUT_DATA_CREATE));
-
- writeTransaction = dataBroker.newWriteOnlyTransaction();
- builder = new MyList1Builder().withKey(new MyList1Key("Althea")).setMyLeaf12("Bertha");
- writeTransaction.mergeParentStructureMerge(LogicalDatastoreType.CONFIGURATION, iid, builder.build());
- writeTransaction.commit();
- adapter.assertGot(getNotifJson(JSON_NOTIF_WITHOUT_DATA_UPDATE));
-
- writeTransaction = dataBroker.newWriteOnlyTransaction();
- writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, iid);
- writeTransaction.commit();
- adapter.assertGot(getNotifJson(JSON_NOTIF_WITHOUT_DATA_DELETE));
- }
-}
+++ /dev/null
-/*
- * 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.sal.streams.listeners;
-
-import static java.util.Objects.requireNonNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.io.FileNotFoundException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.junit.MockitoJUnitRunner;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
-import org.opendaylight.mdsal.dom.api.DOMNotification;
-import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping.NotificationOutputType;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.QNameModule;
-import org.opendaylight.yangtools.yang.common.Revision;
-import org.opendaylight.yangtools.yang.common.XMLNamespace;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
-
-@RunWith(MockitoJUnitRunner.StrictStubs.class)
-public class NotificationListenerTest {
- private static final QNameModule MODULE = QNameModule.create(XMLNamespace.of("notifi:mod"),
- Revision.of("2016-11-23"));
-
- private static EffectiveModelContext schemaContext;
-
- private ControllerContext controllerContext;
-
- @BeforeClass
- public static void staticInit() throws FileNotFoundException {
- schemaContext = TestUtils.loadSchemaContext("/notifications");
- }
-
- @Before
- public void init() {
- controllerContext = TestRestconfUtils.newControllerContext(schemaContext);
- }
-
- @Test
- public void notifi_leafTest() {
- final Absolute schemaPathNotifi = Absolute.of(QName.create(MODULE, "notifi-leaf"));
-
- final DOMNotification notificationData = mock(DOMNotification.class);
-
- final LeafNode<String> leaf = mockLeaf(QName.create(MODULE, "lf"));
- final ContainerNode notifiBody = mockCont(schemaPathNotifi.lastNodeIdentifier(), leaf);
-
- when(notificationData.getType()).thenReturn(schemaPathNotifi);
- when(notificationData.getBody()).thenReturn(notifiBody);
-
- final String result = prepareJson(notificationData, schemaPathNotifi);
-
- assertTrue(result.contains("ietf-restconf:notification"));
- assertTrue(result.contains("event-time"));
- assertTrue(result.contains("notifi-module:notifi-leaf"));
- assertTrue(result.contains("lf" + '"' + ":" + '"' + "value"));
- }
-
- @Test
- public void notifi_cont_leafTest() {
- final Absolute schemaPathNotifi = Absolute.of(QName.create(MODULE, "notifi-cont"));
-
- final DOMNotification notificationData = mock(DOMNotification.class);
-
- final LeafNode<String> leaf = mockLeaf(QName.create(MODULE, "lf"));
- final ContainerNode cont = mockCont(QName.create(MODULE, "cont"), leaf);
- final ContainerNode notifiBody = mockCont(schemaPathNotifi.lastNodeIdentifier(), cont);
-
- when(notificationData.getType()).thenReturn(schemaPathNotifi);
- when(notificationData.getBody()).thenReturn(notifiBody);
-
- final String result = prepareJson(notificationData, schemaPathNotifi);
-
- assertTrue(result.contains("ietf-restconf:notification"));
- assertTrue(result.contains("event-time"));
- assertTrue(result.contains("notifi-module:notifi-cont"));
- assertTrue(result.contains("cont"));
- assertTrue(result.contains("lf" + '"' + ":" + '"' + "value"));
- }
-
- @Test
- public void notifi_list_Test() {
- final Absolute schemaPathNotifi = Absolute.of(QName.create(MODULE, "notifi-list"));
-
- final ContainerNode notifiBody = mockCont(schemaPathNotifi.lastNodeIdentifier(), ImmutableNodes.mapNodeBuilder()
- .withNodeIdentifier(NodeIdentifier.create(QName.create(MODULE, "lst")))
- .withChild(mockMapEntry(QName.create(MODULE, "lst"), mockLeaf(QName.create(MODULE, "lf"))))
- .build());
-
- final DOMNotification notificationData = mock(DOMNotification.class);
- when(notificationData.getType()).thenReturn(schemaPathNotifi);
- when(notificationData.getBody()).thenReturn(notifiBody);
-
- final String result = prepareJson(notificationData, schemaPathNotifi);
-
- assertTrue(result.contains("ietf-restconf:notification"));
- assertTrue(result.contains("event-time"));
- assertTrue(result.contains("notifi-module:notifi-list"));
- assertTrue(result.contains("lst"));
- assertTrue(result.contains("lf" + '"' + ":" + '"' + "value"));
- }
-
- @Test
- public void notifi_grpTest() {
- final Absolute schemaPathNotifi = Absolute.of(QName.create(MODULE, "notifi-grp"));
-
- final DOMNotification notificationData = mock(DOMNotification.class);
-
- final LeafNode<String> leaf = mockLeaf(QName.create(MODULE, "lf"));
- final ContainerNode notifiBody = mockCont(schemaPathNotifi.lastNodeIdentifier(), leaf);
-
- when(notificationData.getType()).thenReturn(schemaPathNotifi);
- when(notificationData.getBody()).thenReturn(notifiBody);
-
- final String result = prepareJson(notificationData, schemaPathNotifi);
-
- assertTrue(result.contains("ietf-restconf:notification"));
- assertTrue(result.contains("event-time"));
- assertTrue(result.contains("lf" + '"' + ":" + '"' + "value"));
- }
-
- @Test
- public void notifi_augmTest() {
- final Absolute schemaPathNotifi = Absolute.of(QName.create(MODULE, "notifi-augm"));
-
- final DOMNotification notificationData = mock(DOMNotification.class);
-
- final LeafNode<String> leaf = mockLeaf(QName.create(MODULE, "lf-augm"));
- final AugmentationNode augm = mockAugm(leaf);
- final ContainerNode notifiBody = mockCont(schemaPathNotifi.lastNodeIdentifier(), augm);
-
- when(notificationData.getType()).thenReturn(schemaPathNotifi);
- when(notificationData.getBody()).thenReturn(notifiBody);
-
- final String result = prepareJson(notificationData, schemaPathNotifi);
-
- assertTrue(result.contains("ietf-restconf:notification"));
- assertTrue(result.contains("event-time"));
- assertTrue(result.contains("lf-augm" + '"' + ":" + '"' + "value"));
- }
-
- private static AugmentationNode mockAugm(final LeafNode<String> leaf) {
- final AugmentationNode augm = mock(AugmentationNode.class);
- final AugmentationIdentifier augmId = new AugmentationIdentifier(Set.of(leaf.getIdentifier().getNodeType()));
- when(augm.getIdentifier()).thenReturn(augmId);
-
- final Collection<DataContainerChild> childs = new ArrayList<>();
- childs.add(leaf);
-
- when(augm.body()).thenReturn(childs);
- return augm;
- }
-
- private static MapEntryNode mockMapEntry(final QName entryQName, final LeafNode<String> leaf) {
- return Builders.mapEntryBuilder()
- .withNodeIdentifier(NodeIdentifierWithPredicates.of(entryQName, leaf.getIdentifier().getNodeType(),
- leaf.body()))
- .withChild(leaf)
- .build();
- }
-
- private static ContainerNode mockCont(final QName contQName, final DataContainerChild child) {
- return Builders.containerBuilder()
- .withNodeIdentifier(NodeIdentifier.create(contQName))
- .withChild(child)
- .build();
- }
-
- private static LeafNode<String> mockLeaf(final QName leafQName) {
- return ImmutableNodes.leafNode(leafQName, "value");
- }
-
- private String prepareJson(final DOMNotification notificationData, final Absolute schemaPathNotifi) {
- final List<NotificationListenerAdapter> listNotifi = Notificator.createNotificationListener(
- List.of(schemaPathNotifi), "stream-name", NotificationOutputType.JSON.toString(), controllerContext);
- final NotificationListenerAdapter notifi = listNotifi.get(0);
- return requireNonNull(notifi.prepareJson(schemaContext, notificationData));
- }
-}
+++ /dev/null
-/*
- * 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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev131019;
-
-import static org.junit.Assert.assertNotNull;
-
-import org.junit.Test;
-
-public class DatastoreIdentifierBuilderTest {
-
- @Test(expected = IllegalArgumentException.class)
- public void testDatastoreIdentifierBuilder() {
- final DatastoreIdentifierBuilder datastoreIdentifierBuilder = new DatastoreIdentifierBuilder();
- assertNotNull(datastoreIdentifierBuilder);
- DatastoreIdentifierBuilder.getDefaultInstance("");
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev131019.restconf.restconf.modules;
-
-import static junit.framework.TestCase.assertTrue;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import com.google.common.collect.ImmutableSet;
-import java.util.Set;
-import org.junit.Test;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev131019.RevisionIdentifier;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.YangIdentifier;
-
-public class ModuleBuilderTest {
-
- @Test
- public void testModuleBuilder() {
- final ModuleBuilder moduleBuilder = new ModuleBuilder();
- final Module.Revision revision = new Module.Revision(new RevisionIdentifier("2016-10-11"));
- final YangIdentifier yangIdentifierOne = new YangIdentifier("YangIdentifier1");
- final YangIdentifier yangIdentifierTwo = new YangIdentifier("YangIdentifier2");
- final Uri namespace = new Uri("namespace");
- final Set<YangIdentifier> yangIdentifierList = ImmutableSet.of(yangIdentifierOne, yangIdentifierTwo);
- final ModuleKey moduleKeyOne = new ModuleKey(yangIdentifierOne, revision);
- final ModuleKey moduleKeyTwo = new ModuleKey(moduleKeyOne);
- moduleBuilder.setRevision(revision);
- moduleBuilder.setDeviation(yangIdentifierList);
- moduleBuilder.setFeature(yangIdentifierList);
- moduleBuilder.setName(yangIdentifierOne);
- moduleBuilder.setNamespace(namespace);
- moduleBuilder.withKey(moduleKeyOne);
- final Module moduleOne = moduleBuilder.build();
- final Module moduleTwo = new ModuleBuilder(moduleOne).build();
-
- assertNotNull(moduleBuilder);
- assertNotNull(revision);
- assertNotNull(yangIdentifierOne);
- assertNotNull(yangIdentifierTwo);
- assertNotNull(namespace);
- assertNotNull(yangIdentifierList);
- assertNotNull(moduleKeyOne);
- assertNotNull(moduleKeyOne.hashCode());
- assertNotNull(moduleKeyOne.toString());
- assertNotNull(moduleBuilder.toString());
- assertNotNull(moduleBuilder.hashCode());
-
- assertEquals(moduleKeyOne, moduleKeyTwo);
- assertEquals(revision, moduleKeyOne.getRevision());
- assertEquals(yangIdentifierOne, moduleKeyOne.getName());
- assertEquals(revision, moduleBuilder.getRevision());
- assertEquals(yangIdentifierList, moduleBuilder.getDeviation());
- assertEquals(yangIdentifierList, moduleBuilder.getFeature());
- assertEquals(yangIdentifierOne, moduleBuilder.getName());
- assertEquals(namespace, moduleBuilder.getNamespace());
- assertEquals(moduleKeyOne, moduleBuilder.key());
- assertEquals(moduleOne.toString(), moduleTwo.toString());
- assertEquals(moduleKeyOne.toString(), moduleKeyTwo.toString());
-
- assertTrue(moduleOne.equals(moduleTwo));
- assertTrue(moduleKeyOne.equals(moduleKeyTwo));
- }
-}
+++ /dev/null
-/*
- * 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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev131019.restconf.restconf.modules;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import org.junit.Test;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev131019.restconf.restconf.modules.Module.Revision;
-
-public class ModuleRevisionBuilderTest {
-
- @Test
- public void testModuleRevisionBuilder() {
- final ModuleRevisionBuilder moduleRevisionBuilder = new ModuleRevisionBuilder();
- assertNotNull(moduleRevisionBuilder);
- final Revision revision = ModuleRevisionBuilder.getDefaultInstance("");
- assertNotNull(revision);
- assertEquals("", revision.getString());
- assertEquals(null, revision.getRevisionIdentifier());
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 Brocade Communications 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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev131019.restconf.restconf.modules;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import org.junit.Test;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev131019.RevisionIdentifier;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev131019.restconf.restconf.modules.Module.Revision;
-
-public class RevisionBuilderTest {
- @Test
- public void testEmptyString() {
- final RevisionBuilder revisionBuilder = new RevisionBuilder();
- assertNotNull(revisionBuilder);
- final Revision revision = RevisionBuilder.getDefaultInstance("");
- validate(revision, "", null);
- }
-
- @Test
- public void testValidDataString() {
- final String dateString = "2014-04-23";
- final Revision revision = RevisionBuilder.getDefaultInstance(dateString);
- validate(revision, null, new RevisionIdentifier(dateString));
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testNullString() {
- RevisionBuilder.getDefaultInstance(null);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testBadFormatString() {
- RevisionBuilder.getDefaultInstance("badFormat");
- }
-
- private static void validate(final Revision revisionUnderTest, final String expectedRevisionString,
- final RevisionIdentifier expectedRevisionIdentifier) {
- assertNotNull(revisionUnderTest);
- assertEquals(expectedRevisionString, revisionUnderTest.getString());
- assertEquals(expectedRevisionIdentifier, revisionUnderTest.getRevisionIdentifier());
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "main:cont":{
- "augment-main-a:cont1":{
- "lf11":"lf11 value from a"
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "main:cont":{
- "augment-main-b:cont1":{
- "lf11":"lf11 value from b"
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-<cont xmlns="ns:main">
- <cont1 xmlns="ns:augment:main:a">
- <lf11>lf11 value for a</lf11>
- </cont1>
-</cont>
\ No newline at end of file
+++ /dev/null
-<cont xmlns="ns:main">
- <cont1 xmlns="ns:augment:main:b">
- <lf11>lf11 value for b</lf11>
- </cont1>
-</cont>
\ No newline at end of file
+++ /dev/null
-module augment-main-a {
- namespace "ns:augment:main:a";
- prefix "aumaa";
-
-
- import main {prefix mn; revision-date 2014-01-21;}
-
-
- revision "2014-01-21" {
- }
-
- augment "/mn:cont" {
- container cont1 {
- leaf lf11 {
- type string;
- }
- }
- }
-
-}
+++ /dev/null
-module augment-main-b {
- namespace "ns:augment:main:b";
- prefix "aumab";
-
-
- import main {prefix mn; revision-date 2014-01-21;}
-
-
- revision "2014-01-21" {
- }
-
- augment "/mn:cont" {
- container cont1 {
- leaf lf11 {
- type string;
- }
- }
- }
-
-}
+++ /dev/null
-module main {
- namespace "ns:main";
- prefix "ma";
-
- revision "2014-01-21" {
- }
-
- container cont {
- }
-}
\ No newline at end of file
+++ /dev/null
-module opendaylight-inventory {
- namespace "urn:opendaylight:inventory";
- prefix inv;
-
- revision "2013-08-19" {
- description "Initial revision of Inventory model";
- }
-
-
- container nodes {
- list node {
- key "id";
- leaf id {
- type string;
- }
- }
- }
-
-}
+++ /dev/null
-module sal-remote-augment {
-
- yang-version 1;
- namespace "urn:sal:restconf:event:subscription";
- prefix "salrmt-aug-ev-subscr";
-
- import sal-remote {prefix salrmt; revision-date "2014-01-14";}
-
- description
- "Added input parameters to rpc create-data-change-event-subscription";
-
- revision "2014-07-08" {
- }
-
- augment "/salrmt:create-data-change-event-subscription/salrmt:input" {
- leaf datastore {
- type enumeration {
- enum OPERATIONAL;
- enum CONFIGURATION;
- }
- }
- leaf scope {
- type enumeration {
- enum BASE;
- enum ONE;
- enum SUBTREE;
- }
- }
- leaf notification-output-type {
- type enumeration {
- enum JSON;
- enum XML;
- }
- default "XML";
- description "Input parameter which type of output will be parsed on notification";
- }
- }
-
-}
+++ /dev/null
-module sal-remote {
-
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote";
- prefix "sal-remote";
-
-
- organization "Cisco Systems, Inc.";
- contact "Martin Bobak <mbobak@cisco.com>";
-
- description
- "This module contains the definition of methods related to
- sal remote model.
-
- Copyright (c)2013 Cisco Systems, Inc. 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";
-
- revision "2014-01-14" {
- description
- "Initial revision";
- }
-
-
- typedef q-name {
- type string;
- reference
- "http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#QName";
- }
-
- rpc create-data-change-event-subscription {
- input {
- leaf path {
- type instance-identifier;
- description "Subtree path. ";
- }
- }
- output {
- leaf stream-name {
- type string;
- description "Notification stream name.";
- }
- }
- }
-
- notification data-changed-notification {
- description "Data change notification.";
- list data-change-event {
- key path;
- leaf path {
- type instance-identifier;
- }
- leaf store {
- type enumeration {
- enum config;
- enum operation;
- }
- }
- leaf operation {
- type enumeration {
- enum created;
- enum updated;
- enum deleted;
- }
- }
- anyxml data{
- description "DataObject ";
- }
- }
- }
-
- rpc create-notification-stream {
- input {
- leaf-list notifications {
- type q-name;
- description "Notification QNames";
- }
- }
- output {
- leaf notification-stream-identifier {
- type string;
- description "Unique notification stream identifier, in which notifications will be propagated";
- }
- }
- }
-
- rpc begin-transaction{
- output{
- anyxml data-modification-transaction{
- description "DataModificationTransaction xml";
- }
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
- module number {
-
- namespace "number";
- prefix "number";
-
- revision 2014-04-24 {
- }
-
-
-
- container cont {
- leaf lf {
- type uint8;
- }
-
- }
- }
+++ /dev/null
-{
- "cont":{
- "cont1":[
- {
- "lst11":{
- "lf111":"value1"
- }
- },
- {
- "lst11":{
- "lf111":"value2"
- }
- }
- ]
- }
-}
\ No newline at end of file
+++ /dev/null
-<cont>
- <cont1>
- <lst11>
- <lf111>value1</lf111>
- </lst11>
- </cont1>
- <cont1>
- <lst11>
- <lf111>value1</lf111>
- </lst11>
- </cont1>
-</cont>
\ No newline at end of file
+++ /dev/null
-{
- "cont":{
- "cont1":{
- "lst11":[
- {
- "lf111":"value1",
- "lf111":"value2"
- },
- {
- "lf111":"value3"
- }
- ]
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-<cont>
- <cont1>
- <lst11>
- <lf111>value1</lf111>,
- <lf111>value2</lf111>,
- </lst11>
- <lst11>
- <lf111>value3</lf111>,
- </lst11>
- </cont1>
-</cont>
\ No newline at end of file
+++ /dev/null
-/* bug 1204 */
-module equal-data-node-names {
- namespace "ns:equal:data:node:names";
-
- prefix "eqdanona";
- revision 2014-06-26 {
- }
-
- container cont {
- container cont1 {
- list lst11 {
- leaf lf111 {
- type string;
- }
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>\r
-<top-level-list xmlns="foo">\r
- <key-leaf>key-value</key-leaf>\r
- <ordinary-leaf>leaf-value</ordinary-leaf>\r
-</top-level-list>
\ No newline at end of file
+++ /dev/null
-module foo {\r
- namespace foo;\r
- prefix foo;\r
-\r
- revision 2017-08-09;\r
-\r
- list top-level-list {\r
- key key-leaf;\r
-\r
- leaf key-leaf {\r
- type string;\r
- }\r
-\r
- leaf ordinary-leaf {\r
- type string;\r
- }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-{
- "input" :
- {
- "toaster:toasterDoneness" : "10",
- "toaster:toasterToastType": "wheat-bread"
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "test-module:input":{
- "cont":{
- "cont1":{
- "lf11":"lf1 data",
- "lf12":"lf2 data"
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-<input xmlns="test:module">
- <cont>
- <cont1>
- <lf11>lf1 data</lf11>
- <lf12>lf2 data</lf12>
- </cont1>
- </cont>
-</input>
\ No newline at end of file
+++ /dev/null
-<cont xmlns="test:module">
- <cont1>
- <lf11>lf1 data</lf11>
- <lf12>lf2 data</lf12>
- </cont1>
-</cont>
+++ /dev/null
-<cont1 xmlns="test:module">
- <lf11>lf1 data</lf11>
- <lf12>lf2 data</lf12>
-</cont1>
+++ /dev/null
-
-<cont1 xmlns="test:module">
- <lf11>lf1 data</lf11>
- <lf12>lf2 data</lf12>
-</cont1>
-
+++ /dev/null
-<interfaces xmlns="test:module">
- <class>
- <name>John</name>
- <address>F.C.I 43</address>
- <email>j@j</email>
- </class>
-</interfaces>
-
+++ /dev/null
-<class xmlns="test:module">
- <name>John</name>
- <address>F.C.I 43</address>
- <email>j@j</email>
-</class>
-
+++ /dev/null
-<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <cont xmlns="test:module">
- <cont1>
- <lf11>lf1 data</lf11>
- <lf12>lf2 data</lf12>
- </cont1>
- </cont>
-</data>
\ No newline at end of file
+++ /dev/null
-module test-module {
- namespace "test:module";
- prefix tstmod;
-
- revision 2014-01-09 {
- }
-
- identity module-type {
- }
-
- identity test-identity {
- }
-
- container interfaces {
- container class {
- leaf name {
- type string;
- }
- leaf address {
- type string;
- }
- leaf email {
- type string;
- }
- }
- }
-
- container cont {
- container cont1 {
- leaf lf11 {
- type string;
- }
- leaf lf12 {
- type string;
- }
- }
- list lst1 {
- key "lf11";
- leaf lf11 {
- type string;
- }
- }
- }
-
- container modules {
- list module {
- key "type name";
- leaf name {
- type string;
- mandatory true;
- }
-
- leaf type {
- type identityref {
- base module-type;
- }
- mandatory true;
- }
-
- leaf data {
- type string;
- }
- }
- }
-
- list lst-with-composite-key {
- key "key1 key2";
- leaf key1 {
- type string;
- }
- leaf key2 {
- type uint8;
- }
- }
-
- rpc no-payload-rpc-test {
- output {
- container cont-output {
- }
- }
- }
-
- rpc rpc-test {
- input {
- container cont {
- container cont1 {
- leaf lf11 {
- type string;
- }
- leaf lf12 {
- type string;
- }
- }
- }
- }
- output {
- container cont-output {
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "cont1": {
- "lf11": "lf11 data",
- "lf12": "lf12 data"
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "ietf-restconf:yang-patch" : {
- "patch-id" : "0",
- "edit" : [
- {
- "edit-id" : "edit1",
- "operation" : "create",
- "target" : "",
- "value" :
- {
- "cont1":
- {
- "lf11": "lf11 data",
- "lf12": "lf12 data"
- }
- }
- }
- ]
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "interfaces": {
- "interface": [
- {
- "name": "eth0",
- "type": "ethernetCsmacd",
- "enabled": false
- },
- {
- "name": "eth1",
- "type": "ethernetCsmacd",
- "enabled": true,
- "vlan-tagging": true
- },
- {
- "name": "eth1.10",
- "type": "l2vlan",
- "enabled": true,
- "base-interface": "eth1",
- "vlan-id": 10
- },
- {
- "name": "lo1",
- "type": "softwareLoopback",
- "enabled": true
- }
- ]
- },
- "interfaces-state": {
- "interface": [
- {
- "name": "eth0",
- "type": "ethernetCsmacd",
- "admin-status": "down",
- "oper-status": "down",
- "if-index": 2,
- "phys-address": "00:01:02:03:04:05",
- "statistics": {
- "discontinuity-time": "2013-04-01T03:00:00+00:00"
- }
- },
- {
- "name": "eth1",
- "type": "ethernetCsmacd",
- "admin-status": "up",
- "oper-status": "up",
- "if-index": 7,
- "phys-address": "00:01:02:03:04:06",
- "higher-layer-if": [
- "eth1.10"
- ],
- "statistics": {
- "discontinuity-time": "2013-04-01T03:00:00+00:00"
- }
- },
- {
- "name": "eth1.10",
- "type": "l2vlan",
- "admin-status": "up",
- "oper-status": "up",
- "if-index": 9,
- "lower-layer-if": [
- "eth1"
- ],
- "statistics": {
- "discontinuity-time": "2013-04-01T03:00:00+00:00"
- }
- },
- {
- "name": "eth2",
- "type": "ethernetCsmacd",
- "admin-status": "down",
- "oper-status": "down",
- "if-index": 8,
- "phys-address": "00:01:02:03:04:07",
- "statistics": {
- "discontinuity-time": "2013-04-01T03:00:00+00:00"
- }
- },
- {
- "name": "lo1",
- "type": "softwareLoopback",
- "admin-status": "up",
- "oper-status": "up",
- "if-index": 1,
- "statistics": {
- "discontinuity-time": "2013-04-01T03:00:00+00:00"
- }
- }
- ]
- }
-}
\ No newline at end of file
+++ /dev/null
-<rpc-reply
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
- message-id="101">
- <data>
-
- <interfaces
- xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"
- xmlns:vlan="http://example.com/vlan">
-
- <interface>
- <name>eth0</name>
- <type>ethernetCsmacd</type>
- <enabled>false</enabled>
- </interface>
-
- <interface>
- <name>eth1</name>
- <type>ethernetCsmacd</type>
- <enabled>true</enabled>
- <vlan:vlan-tagging>true</vlan:vlan-tagging>
- </interface>
-
- <interface>
- <name>eth1.10</name>
- <type>l2vlan</type>
- <enabled>true</enabled>
- <vlan:base-interface>eth1</vlan:base-interface>
- <vlan:vlan-id>10</vlan:vlan-id>
- </interface>
-
- <interface>
- <name>lo1</name>
- <type>softwareLoopback</type>
- <enabled>true</enabled>
- </interface>
-
- </interfaces>
-
- <interfaces-state
- xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
-
- <interface>
- <name>eth0</name>
- <type>ethernetCsmacd</type>
- <admin-status>down</admin-status>
- <oper-status>down</oper-status>
- <if-index>2</if-index>
- <phys-address>00:01:02:03:04:05</phys-address>
- <statistics>
- <discontinuity-time>
- 2013-04-01T03:00:00+00:00
- </discontinuity-time>
- <!-- counters now shown here -->
- </statistics>
- </interface>
-
- <interface>
- <name>eth1</name>
- <type>ethernetCsmacd</type>
- <admin-status>up</admin-status>
- <oper-status>up</oper-status>
- <if-index>7</if-index>
- <phys-address>00:01:02:03:04:06</phys-address>
- <higher-layer-if>eth1.10</higher-layer-if>
- <statistics>
- <discontinuity-time>
- 2013-04-01T03:00:00+00:00
- </discontinuity-time>
- <!-- counters now shown here -->
- </statistics>
- </interface>
-
- <interface>
- <name>eth1.10</name>
- <type>l2vlan</type>
- <admin-status>up</admin-status>
- <oper-status>up</oper-status>
- <if-index>9</if-index>
- <lower-layer-if>eth1</lower-layer-if>
- <statistics>
- <discontinuity-time>
- 2013-04-01T03:00:00+00:00
- </discontinuity-time>
- <!-- counters now shown here -->
- </statistics>
- </interface>
-
- <!-- This interface is not configured -->
- <interface>
- <name>eth2</name>
- <type>ethernetCsmacd</type>
- <admin-status>down</admin-status>
- <oper-status>down</oper-status>
- <if-index>8</if-index>
- <phys-address>00:01:02:03:04:07</phys-address>
- <statistics>
- <discontinuity-time>
- 2013-04-01T03:00:00+00:00
- </discontinuity-time>
- <!-- counters now shown here -->
- </statistics>
- </interface>
-
- <interface>
- <name>lo1</name>
- <type>softwareLoopback</type>
- <admin-status>up</admin-status>
- <oper-status>up</oper-status>
- <if-index>1</if-index>
- <statistics>
- <discontinuity-time>
- 2013-04-01T03:00:00+00:00
- </discontinuity-time>
- <!-- counters now shown here -->
- </statistics>
- </interface>
-
- </interfaces-state>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-module ex-vlan {
- namespace "http://example.com/vlan";
- prefix "vlan";
-
- import ietf-interfaces {
- prefix if;
- }
-
- revision 2013-10-22 {
- description
- "Initial revision.";
- reference
- "RFC A YANG Data Model for Interface Management draft-ietf-netmod-interfaces-cfg-12 - Appendix C";
- }
-
- augment "/if:interfaces/if:interface" {
- when "if:type = 'ethernetCsmacd' or
- if:type = 'ieee8023adLag'";
- leaf vlan-tagging {
- type boolean;
- default false;
- }
- }
-
- augment "/if:interfaces/if:interface" {
- when "if:type = 'l2vlan'";
-
- leaf base-interface {
- type if:interface-ref;
- must "/if:interfaces/if:interface[if:name = current()]"
- + "/vlan:vlan-tagging = 'true'" {
- description
- "The base interface must have vlan tagging enabled.";
- }
- }
- leaf vlan-id {
- type uint16 {
- range "1..4094";
- }
- must "../base-interface" {
- description
- "If a vlan-id is defined, a base-interface must
- be specified.";
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-module iana-if-type {
- namespace "urn:ietf:params:xml:ns:yang:iana-if-type";
- prefix ianaift;
-
- organization "IANA";
- contact
- " Internet Assigned Numbers Authority
-
- Postal: ICANN
- 4676 Admiralty Way, Suite 330
- Marina del Rey, CA 90292
-
- Tel: +1 310 823 9358
- E-Mail: iana&iana.org";
- description
- "This YANG module defines the iana-if-type typedef, which
- contains YANG definitions for IANA-registered interface types.
-
- This YANG module is maintained by IANA, and reflects the
- 'ifType definitions' registry.
-
- The latest revision of this YANG module can be obtained from
- the IANA web site.
-
- Copyright (c) 2011 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 XXXX; see
- the RFC itself for full legal notices.";
- // RFC Ed.: replace XXXX with actual RFC number and remove this
- // note.
-
- // RFC Ed.: update the date below with the date of RFC publication
- // and remove this note.
- revision 2013-07-04 {
- description
- "Initial revision.";
- reference
- "RFC XXXX: IANA Interface Type YANG Module";
- }
-
- typedef iana-if-type {
- type enumeration {
- enum "other" {
- value 1;
- description
- "None of the following";
- }
- enum "regular1822" {
- value 2;
- }
- enum "hdh1822" {
- value 3;
- }
- enum "ddnX25" {
- value 4;
- }
- enum "rfc877x25" {
- value 5;
- reference
- "RFC 1382 - SNMP MIB Extension for the X.25 Packet Layer";
- }
- enum "ethernetCsmacd" {
- value 6;
- description
- "For all ethernet-like interfaces, regardless of speed,
- as per RFC3635.";
- reference
- "RFC 3635 - Definitions of Managed Objects for the
- Ethernet-like Interface Types.";
- }
- enum "iso88023Csmacd" {
- value 7;
- status deprecated;
- description
- "Deprecated via RFC3635.
- Use ethernetCsmacd(6) instead.";
- reference
- "RFC 3635 - Definitions of Managed Objects for the
- Ethernet-like Interface Types.";
- }
- enum "iso88024TokenBus" {
- value 8;
- }
- enum "iso88025TokenRing" {
- value 9;
- }
- enum "iso88026Man" {
- value 10;
- }
- enum "starLan" {
- value 11;
- status deprecated;
- description
- "Deprecated via RFC3635.
- Use ethernetCsmacd(6) instead.";
- reference
- "RFC 3635 - Definitions of Managed Objects for the
- Ethernet-like Interface Types.";
- }
- enum "proteon10Mbit" {
- value 12;
- }
- enum "proteon80Mbit" {
- value 13;
- }
- enum "hyperchannel" {
- value 14;
- }
- enum "fddi" {
- value 15;
- reference
- "RFC 1512 - FDDI Management Information Base";
- }
- enum "lapb" {
- value 16;
- reference
- "RFC 1381 - SNMP MIB Extension for X.25 LAPB";
- }
- enum "sdlc" {
- value 17;
- }
- enum "ds1" {
- value 18;
- description
- "DS1-MIB";
- reference
- "RFC 4805 - Definitions of Managed Objects for the
- DS1, J1, E1, DS2, and E2 Interface Types";
- }
- enum "e1" {
- value 19;
- status obsolete;
- description
- "Obsolete see DS1-MIB";
- reference
- "RFC 4805 - Definitions of Managed Objects for the
- DS1, J1, E1, DS2, and E2 Interface Types";
- }
- enum "basicISDN" {
- value 20;
- description
- "see also RFC2127";
- }
- enum "primaryISDN" {
- value 21;
- }
- enum "propPointToPointSerial" {
- value 22;
- description
- "proprietary serial";
- }
- enum "ppp" {
- value 23;
- }
- enum "softwareLoopback" {
- value 24;
- }
- enum "eon" {
- value 25;
- description
- "CLNP over IP";
- }
- enum "ethernet3Mbit" {
- value 26;
- }
- enum "nsip" {
- value 27;
- description
- "XNS over IP";
- }
- enum "slip" {
- value 28;
- description
- "generic SLIP";
- }
- enum "ultra" {
- value 29;
- description
- "ULTRA technologies";
- }
- enum "ds3" {
- value 30;
- description
- "DS3-MIB";
- reference
- "RFC 3896 - Definitions of Managed Objects for the
- DS3/E3 Interface Type";
- }
- enum "sip" {
- value 31;
- description
- "SMDS, coffee";
- reference
- "RFC 1694 - Definitions of Managed Objects for SMDS
- Interfaces using SMIv2";
- }
- enum "frameRelay" {
- value 32;
- description
- "DTE only.";
- reference
- "RFC 2115 - Management Information Base for Frame Relay
- DTEs Using SMIv2";
- }
- enum "rs232" {
- value 33;
- reference
- "RFC 1659 - Definitions of Managed Objects for RS-232-like
- Hardware Devices using SMIv2";
- }
- enum "para" {
- value 34;
- description
- "parallel-port";
- reference
- "RFC 1660 - Definitions of Managed Objects for
- Parallel-printer-like Hardware Devices using
- SMIv2";
- }
- enum "arcnet" {
- value 35;
- description
- "arcnet";
- }
- enum "arcnetPlus" {
- value 36;
- description
- "arcnet plus";
- }
- enum "atm" {
- value 37;
- description
- "ATM cells";
- }
- enum "miox25" {
- value 38;
- reference
- "RFC 1461 - SNMP MIB extension for Multiprotocol
- Interconnect over X.25";
- }
- enum "sonet" {
- value 39;
- description
- "SONET or SDH";
- }
- enum "x25ple" {
- value 40;
- reference
- "RFC 2127 - ISDN Management Information Base using SMIv2";
- }
- enum "iso88022llc" {
- value 41;
- }
- enum "localTalk" {
- value 42;
- }
- enum "smdsDxi" {
- value 43;
- }
- enum "frameRelayService" {
- value 44;
- description
- "FRNETSERV-MIB";
- reference
- "RFC 2954 - Definitions of Managed Objects for Frame
- Relay Service";
- }
- enum "v35" {
- value 45;
- }
- enum "hssi" {
- value 46;
- }
- enum "hippi" {
- value 47;
- }
- enum "modem" {
- value 48;
- description
- "Generic modem";
- }
- enum "aal5" {
- value 49;
- description
- "AAL5 over ATM";
- }
- enum "sonetPath" {
- value 50;
- }
- enum "sonetVT" {
- value 51;
- }
- enum "smdsIcip" {
- value 52;
- description
- "SMDS InterCarrier Interface";
- }
- enum "propVirtual" {
- value 53;
- description
- "proprietary virtual/internal";
- reference
- "RFC 2863 - The Interfaces Group MIB";
- }
- enum "propMultiplexor" {
- value 54;
- description
- "proprietary multiplexing";
- reference
- "RFC 2863 - The Interfaces Group MIB";
- }
- enum "ieee80212" {
- value 55;
- description
- "100BaseVG";
- }
- enum "fibreChannel" {
- value 56;
- description
- "Fibre Channel";
- }
- enum "hippiInterface" {
- value 57;
- description
- "HIPPI interfaces";
- }
- enum "frameRelayInterconnect" {
- value 58;
- status obsolete;
- description
- "Obsolete use either
- frameRelay(32) or frameRelayService(44).";
- }
- enum "aflane8023" {
- value 59;
- description
- "ATM Emulated LAN for 802.3";
- }
- enum "aflane8025" {
- value 60;
- description
- "ATM Emulated LAN for 802.5";
- }
- enum "cctEmul" {
- value 61;
- description
- "ATM Emulated circuit";
- }
- enum "fastEther" {
- value 62;
- status deprecated;
- description
- "Obsoleted via RFC3635.
- ethernetCsmacd(6) should be used instead";
- reference
- "RFC 3635 - Definitions of Managed Objects for the
- Ethernet-like Interface Types.";
- }
- enum "isdn" {
- value 63;
- description
- "ISDN and X.25";
- reference
- "RFC 1356 - Multiprotocol Interconnect on X.25 and ISDN
- in the Packet Mode";
- }
- enum "v11" {
- value 64;
- description
- "CCITT V.11/X.21";
- }
- enum "v36" {
- value 65;
- description
- "CCITT V.36";
- }
- enum "g703at64k" {
- value 66;
- description
- "CCITT G703 at 64Kbps";
- }
- enum "g703at2mb" {
- value 67;
- status obsolete;
- description
- "Obsolete see DS1-MIB";
- }
- enum "qllc" {
- value 68;
- description
- "SNA QLLC";
- }
- enum "fastEtherFX" {
- value 69;
- status deprecated;
- description
- "Obsoleted via RFC3635
- ethernetCsmacd(6) should be used instead";
- reference
- "RFC 3635 - Definitions of Managed Objects for the
- Ethernet-like Interface Types.";
- }
- enum "channel" {
- value 70;
- description
- "channel";
- }
- enum "ieee80211" {
- value 71;
- description
- "radio spread spectrum";
- }
- enum "ibm370parChan" {
- value 72;
- description
- "IBM System 360/370 OEMI Channel";
- }
- enum "escon" {
- value 73;
- description
- "IBM Enterprise Systems Connection";
- }
- enum "dlsw" {
- value 74;
- description
- "Data Link Switching";
- }
- enum "isdns" {
- value 75;
- description
- "ISDN S/T interface";
- }
- enum "isdnu" {
- value 76;
- description
- "ISDN U interface";
- }
- enum "lapd" {
- value 77;
- description
- "Link Access Protocol D";
- }
- enum "ipSwitch" {
- value 78;
- description
- "IP Switching Objects";
- }
- enum "rsrb" {
- value 79;
- description
- "Remote Source Route Bridging";
- }
- enum "atmLogical" {
- value 80;
- description
- "ATM Logical Port";
- reference
- "RFC 3606 - Definitions of Supplemental Managed Objects
- for ATM Interface";
- }
- enum "ds0" {
- value 81;
- description
- "Digital Signal Level 0";
- reference
- "RFC 2494 - Definitions of Managed Objects for the DS0
- and DS0 Bundle Interface Type";
- }
- enum "ds0Bundle" {
- value 82;
- description
- "group of ds0s on the same ds1";
- reference
- "RFC 2494 - Definitions of Managed Objects for the DS0
- and DS0 Bundle Interface Type";
- }
- enum "bsc" {
- value 83;
- description
- "Bisynchronous Protocol";
- }
- enum "async" {
- value 84;
- description
- "Asynchronous Protocol";
- }
- enum "cnr" {
- value 85;
- description
- "Combat Net Radio";
- }
- enum "iso88025Dtr" {
- value 86;
- description
- "ISO 802.5r DTR";
- }
- enum "eplrs" {
- value 87;
- description
- "Ext Pos Loc Report Sys";
- }
- enum "arap" {
- value 88;
- description
- "Appletalk Remote Access Protocol";
- }
- enum "propCnls" {
- value 89;
- description
- "Proprietary Connectionless Protocol";
- }
- enum "hostPad" {
- value 90;
- description
- "CCITT-ITU X.29 PAD Protocol";
- }
- enum "termPad" {
- value 91;
- description
- "CCITT-ITU X.3 PAD Facility";
- }
- enum "frameRelayMPI" {
- value 92;
- description
- "Multiproto Interconnect over FR";
- }
- enum "x213" {
- value 93;
- description
- "CCITT-ITU X213";
- }
- enum "adsl" {
- value 94;
- description
- "Asymmetric Digital Subscriber Loop";
- }
- enum "radsl" {
- value 95;
- description
- "Rate-Adapt. Digital Subscriber Loop";
- }
- enum "sdsl" {
- value 96;
- description
- "Symmetric Digital Subscriber Loop";
- }
- enum "vdsl" {
- value 97;
- description
- "Very H-Speed Digital Subscrib. Loop";
- }
- enum "iso88025CRFPInt" {
- value 98;
- description
- "ISO 802.5 CRFP";
- }
- enum "myrinet" {
- value 99;
- description
- "Myricom Myrinet";
- }
- enum "voiceEM" {
- value 100;
- description
- "voice recEive and transMit";
- }
- enum "voiceFXO" {
- value 101;
- description
- "voice Foreign Exchange Office";
- }
- enum "voiceFXS" {
- value 102;
- description
- "voice Foreign Exchange Station";
- }
- enum "voiceEncap" {
- value 103;
- description
- "voice encapsulation";
- }
- enum "voiceOverIp" {
- value 104;
- description
- "voice over IP encapsulation";
- }
- enum "atmDxi" {
- value 105;
- description
- "ATM DXI";
- }
- enum "atmFuni" {
- value 106;
- description
- "ATM FUNI";
- }
- enum "atmIma" {
- value 107;
- description
- "ATM IMA";
- }
- enum "pppMultilinkBundle" {
- value 108;
- description
- "PPP Multilink Bundle";
- }
- enum "ipOverCdlc" {
- value 109;
- description
- "IBM ipOverCdlc";
- }
- enum "ipOverClaw" {
- value 110;
- description
- "IBM Common Link Access to Workstn";
- }
- enum "stackToStack" {
- value 111;
- description
- "IBM stackToStack";
- }
- enum "virtualIpAddress" {
- value 112;
- description
- "IBM VIPA";
- }
- enum "mpc" {
- value 113;
- description
- "IBM multi-protocol channel support";
- }
- enum "ipOverAtm" {
- value 114;
- description
- "IBM ipOverAtm";
- reference
- "RFC 2320 - Definitions of Managed Objects for Classical IP
- and ARP Over ATM Using SMIv2 (IPOA-MIB)";
- }
- enum "iso88025Fiber" {
- value 115;
- description
- "ISO 802.5j Fiber Token Ring";
- }
- enum "tdlc" {
- value 116;
- description
- "IBM twinaxial data link control";
- }
- enum "gigabitEthernet" {
- value 117;
- status deprecated;
- description
- "Obsoleted via RFC3635
- ethernetCsmacd(6) should be used instead";
- reference
- "RFC 3635 - Definitions of Managed Objects for the
- Ethernet-like Interface Types.";
- }
- enum "hdlc" {
- value 118;
- description
- "HDLC";
- }
- enum "lapf" {
- value 119;
- description
- "LAP F";
- }
- enum "v37" {
- value 120;
- description
- "V.37";
- }
- enum "x25mlp" {
- value 121;
- description
- "Multi-Link Protocol";
- }
- enum "x25huntGroup" {
- value 122;
- description
- "X25 Hunt Group";
- }
- enum "transpHdlc" {
- value 123;
- description
- "Transp HDLC";
- }
- enum "interleave" {
- value 124;
- description
- "Interleave channel";
- }
- enum "fast" {
- value 125;
- description
- "Fast channel";
- }
- enum "ip" {
- value 126;
- description
- "IP (for APPN HPR in IP networks)";
- }
- enum "docsCableMaclayer" {
- value 127;
- description
- "CATV Mac Layer";
- }
- enum "docsCableDownstream" {
- value 128;
- description
- "CATV Downstream interface";
- }
- enum "docsCableUpstream" {
- value 129;
- description
- "CATV Upstream interface";
- }
- enum "a12MppSwitch" {
- value 130;
- description
- "Avalon Parallel Processor";
- }
- enum "tunnel" {
- value 131;
- description
- "Encapsulation interface";
- }
- enum "coffee" {
- value 132;
- description
- "coffee pot";
- reference
- "RFC 2325 - Coffee MIB";
- }
- enum "ces" {
- value 133;
- description
- "Circuit Emulation Service";
- }
- enum "atmSubInterface" {
- value 134;
- description
- "ATM Sub Interface";
- }
- enum "l2vlan" {
- value 135;
- description
- "Layer 2 Virtual LAN using 802.1Q";
- }
- enum "l3ipvlan" {
- value 136;
- description
- "Layer 3 Virtual LAN using IP";
- }
- enum "l3ipxvlan" {
- value 137;
- description
- "Layer 3 Virtual LAN using IPX";
- }
- enum "digitalPowerline" {
- value 138;
- description
- "IP over Power Lines";
- }
- enum "mediaMailOverIp" {
- value 139;
- description
- "Multimedia Mail over IP";
- }
- enum "dtm" {
- value 140;
- description
- "Dynamic syncronous Transfer Mode";
- }
- enum "dcn" {
- value 141;
- description
- "Data Communications Network";
- }
- enum "ipForward" {
- value 142;
- description
- "IP Forwarding Interface";
- }
- enum "msdsl" {
- value 143;
- description
- "Multi-rate Symmetric DSL";
- }
- enum "ieee1394" {
- value 144;
- description
- "IEEE1394 High Performance Serial Bus";
- }
- enum "if-gsn" {
- value 145;
- description
- "HIPPI-6400";
- }
- enum "dvbRccMacLayer" {
- value 146;
- description
- "DVB-RCC MAC Layer";
- }
- enum "dvbRccDownstream" {
- value 147;
- description
- "DVB-RCC Downstream Channel";
- }
- enum "dvbRccUpstream" {
- value 148;
- description
- "DVB-RCC Upstream Channel";
- }
- enum "atmVirtual" {
- value 149;
- description
- "ATM Virtual Interface";
- }
- enum "mplsTunnel" {
- value 150;
- description
- "MPLS Tunnel Virtual Interface";
- }
- enum "srp" {
- value 151;
- description
- "Spatial Reuse Protocol";
- }
- enum "voiceOverAtm" {
- value 152;
- description
- "Voice Over ATM";
- }
- enum "voiceOverFrameRelay" {
- value 153;
- description
- "Voice Over Frame Relay";
- }
- enum "idsl" {
- value 154;
- description
- "Digital Subscriber Loop over ISDN";
- }
- enum "compositeLink" {
- value 155;
- description
- "Avici Composite Link Interface";
- }
- enum "ss7SigLink" {
- value 156;
- description
- "SS7 Signaling Link";
- }
- enum "propWirelessP2P" {
- value 157;
- description
- "Prop. P2P wireless interface";
- }
- enum "frForward" {
- value 158;
- description
- "Frame Forward Interface";
- }
- enum "rfc1483" {
- value 159;
- description
- "Multiprotocol over ATM AAL5";
- reference
- "RFC 1483 - Multiprotocol Encapsulation over ATM
- Adaptation Layer 5";
- }
- enum "usb" {
- value 160;
- description
- "USB Interface";
- }
- enum "ieee8023adLag" {
- value 161;
- description
- "IEEE 802.3ad Link Aggregate";
- }
- enum "bgppolicyaccounting" {
- value 162;
- description
- "BGP Policy Accounting";
- }
- enum "frf16MfrBundle" {
- value 163;
- description
- "FRF .16 Multilink Frame Relay";
- }
- enum "h323Gatekeeper" {
- value 164;
- description
- "H323 Gatekeeper";
- }
- enum "h323Proxy" {
- value 165;
- description
- "H323 Voice and Video Proxy";
- }
- enum "mpls" {
- value 166;
- description
- "MPLS";
- }
- enum "mfSigLink" {
- value 167;
- description
- "Multi-frequency signaling link";
- }
- enum "hdsl2" {
- value 168;
- description
- "High Bit-Rate DSL - 2nd generation";
- }
- enum "shdsl" {
- value 169;
- description
- "Multirate HDSL2";
- }
- enum "ds1FDL" {
- value 170;
- description
- "Facility Data Link 4Kbps on a DS1";
- }
- enum "pos" {
- value 171;
- description
- "Packet over SONET/SDH Interface";
- }
- enum "dvbAsiIn" {
- value 172;
- description
- "DVB-ASI Input";
- }
- enum "dvbAsiOut" {
- value 173;
- description
- "DVB-ASI Output";
- }
- enum "plc" {
- value 174;
- description
- "Power Line Communtications";
- }
- enum "nfas" {
- value 175;
- description
- "Non Facility Associated Signaling";
- }
- enum "tr008" {
- value 176;
- description
- "TR008";
- }
- enum "gr303RDT" {
- value 177;
- description
- "Remote Digital Terminal";
- }
- enum "gr303IDT" {
- value 178;
- description
- "Integrated Digital Terminal";
- }
- enum "isup" {
- value 179;
- description
- "ISUP";
- }
- enum "propDocsWirelessMaclayer" {
- value 180;
- description
- "Cisco proprietary Maclayer";
- }
- enum "propDocsWirelessDownstream" {
- value 181;
- description
- "Cisco proprietary Downstream";
- }
- enum "propDocsWirelessUpstream" {
- value 182;
- description
- "Cisco proprietary Upstream";
- }
- enum "hiperlan2" {
- value 183;
- description
- "HIPERLAN Type 2 Radio Interface";
- }
- enum "propBWAp2Mp" {
- value 184;
- description
- "PropBroadbandWirelessAccesspt2multipt use of this value
- for IEEE 802.16 WMAN interfaces as per IEEE Std 802.16f
- is deprecated and ieee80216WMAN(237) should be used
- instead.";
- }
- enum "sonetOverheadChannel" {
- value 185;
- description
- "SONET Overhead Channel";
- }
- enum "digitalWrapperOverheadChannel" {
- value 186;
- description
- "Digital Wrapper";
- }
- enum "aal2" {
- value 187;
- description
- "ATM adaptation layer 2";
- }
- enum "radioMAC" {
- value 188;
- description
- "MAC layer over radio links";
- }
- enum "atmRadio" {
- value 189;
- description
- "ATM over radio links";
- }
- enum "imt" {
- value 190;
- description
- "Inter Machine Trunks";
- }
- enum "mvl" {
- value 191;
- description
- "Multiple Virtual Lines DSL";
- }
- enum "reachDSL" {
- value 192;
- description
- "Long Reach DSL";
- }
- enum "frDlciEndPt" {
- value 193;
- description
- "Frame Relay DLCI End Point";
- }
- enum "atmVciEndPt" {
- value 194;
- description
- "ATM VCI End Point";
- }
- enum "opticalChannel" {
- value 195;
- description
- "Optical Channel";
- }
- enum "opticalTransport" {
- value 196;
- description
- "Optical Transport";
- }
- enum "propAtm" {
- value 197;
- description
- "Proprietary ATM";
- }
- enum "voiceOverCable" {
- value 198;
- description
- "Voice Over Cable Interface";
- }
- enum "infiniband" {
- value 199;
- description
- "Infiniband";
- }
- enum "teLink" {
- value 200;
- description
- "TE Link";
- }
- enum "q2931" {
- value 201;
- description
- "Q.2931";
- }
- enum "virtualTg" {
- value 202;
- description
- "Virtual Trunk Group";
- }
- enum "sipTg" {
- value 203;
- description
- "SIP Trunk Group";
- }
- enum "sipSig" {
- value 204;
- description
- "SIP Signaling";
- }
- enum "docsCableUpstreamChannel" {
- value 205;
- description
- "CATV Upstream Channel";
- }
- enum "econet" {
- value 206;
- description
- "Acorn Econet";
- }
- enum "pon155" {
- value 207;
- description
- "FSAN 155Mb Symetrical PON interface";
- }
- enum "pon622" {
- value 208;
- description
- "FSAN622Mb Symetrical PON interface";
- }
- enum "bridge" {
- value 209;
- description
- "Transparent bridge interface";
- }
- enum "linegroup" {
- value 210;
- description
- "Interface common to multiple lines";
- }
- enum "voiceEMFGD" {
- value 211;
- description
- "voice E&M Feature Group D";
- }
- enum "voiceFGDEANA" {
- value 212;
- description
- "voice FGD Exchange Access North American";
- }
- enum "voiceDID" {
- value 213;
- description
- "voice Direct Inward Dialing";
- }
- enum "mpegTransport" {
- value 214;
- description
- "MPEG transport interface";
- }
- enum "sixToFour" {
- value 215;
- status deprecated;
- description
- "6to4 interface (DEPRECATED)";
- reference
- "RFC 4087 - IP Tunnel MIB";
- }
- enum "gtp" {
- value 216;
- description
- "GTP (GPRS Tunneling Protocol)";
- }
- enum "pdnEtherLoop1" {
- value 217;
- description
- "Paradyne EtherLoop 1";
- }
- enum "pdnEtherLoop2" {
- value 218;
- description
- "Paradyne EtherLoop 2";
- }
- enum "opticalChannelGroup" {
- value 219;
- description
- "Optical Channel Group";
- }
- enum "homepna" {
- value 220;
- description
- "HomePNA ITU-T G.989";
- }
- enum "gfp" {
- value 221;
- description
- "Generic Framing Procedure (GFP)";
- }
- enum "ciscoISLvlan" {
- value 222;
- description
- "Layer 2 Virtual LAN using Cisco ISL";
- }
- enum "actelisMetaLOOP" {
- value 223;
- description
- "Acteleis proprietary MetaLOOP High Speed Link";
- }
- enum "fcipLink" {
- value 224;
- description
- "FCIP Link";
- }
- enum "rpr" {
- value 225;
- description
- "Resilient Packet Ring Interface Type";
- }
- enum "qam" {
- value 226;
- description
- "RF Qam Interface";
- }
- enum "lmp" {
- value 227;
- description
- "Link Management Protocol";
- reference
- "RFC 4327 - Link Management Protocol (LMP) Management
- Information Base (MIB)";
- }
- enum "cblVectaStar" {
- value 228;
- description
- "Cambridge Broadband Networks Limited VectaStar";
- }
- enum "docsCableMCmtsDownstream" {
- value 229;
- description
- "CATV Modular CMTS Downstream Interface";
- }
- enum "adsl2" {
- value 230;
- status deprecated;
- description
- "Asymmetric Digital Subscriber Loop Version 2
- (DEPRECATED/OBSOLETED - please use adsl2plus(238)
- instead)";
- reference
- "RFC 4706 - Definitions of Managed Objects for Asymmetric
- Digital Subscriber Line 2 (ADSL2)";
- }
- enum "macSecControlledIF" {
- value 231;
- description
- "MACSecControlled";
- }
- enum "macSecUncontrolledIF" {
- value 232;
- description
- "MACSecUncontrolled";
- }
- enum "aviciOpticalEther" {
- value 233;
- description
- "Avici Optical Ethernet Aggregate";
- }
- enum "atmbond" {
- value 234;
- description
- "atmbond";
- }
- enum "voiceFGDOS" {
- value 235;
- description
- "voice FGD Operator Services";
- }
- enum "mocaVersion1" {
- value 236;
- description
- "MultiMedia over Coax Alliance (MoCA) Interface
- as documented in information provided privately to IANA";
- }
- enum "ieee80216WMAN" {
- value 237;
- description
- "IEEE 802.16 WMAN interface";
- }
- enum "adsl2plus" {
- value 238;
- description
- "Asymmetric Digital Subscriber Loop Version 2,
- Version 2 Plus and all variants";
- }
- enum "dvbRcsMacLayer" {
- value 239;
- description
- "DVB-RCS MAC Layer";
- reference
- "RFC 5728 - The SatLabs Group DVB-RCS MIB";
- }
- enum "dvbTdm" {
- value 240;
- description
- "DVB Satellite TDM";
- reference
- "RFC 5728 - The SatLabs Group DVB-RCS MIB";
- }
- enum "dvbRcsTdma" {
- value 241;
- description
- "DVB-RCS TDMA";
- reference
- "RFC 5728 - The SatLabs Group DVB-RCS MIB";
- }
- enum "x86Laps" {
- value 242;
- description
- "LAPS based on ITU-T X.86/Y.1323";
- }
- enum "wwanPP" {
- value 243;
- description
- "3GPP WWAN";
- }
- enum "wwanPP2" {
- value 244;
- description
- "3GPP2 WWAN";
- }
- enum "voiceEBS" {
- value 245;
- description
- "voice P-phone EBS physical interface";
- }
- enum "ifPwType" {
- value 246;
- description
- "Pseudowire interface type";
- reference
- "RFC 5601 - Pseudowire (PW) Management Information Base";
- }
- enum "ilan" {
- value 247;
- description
- "Internal LAN on a bridge per IEEE 802.1ap";
- }
- enum "pip" {
- value 248;
- description
- "Provider Instance Port on a bridge per IEEE 802.1ah PBB";
- }
- enum "aluELP" {
- value 249;
- description
- "Alcatel-Lucent Ethernet Link Protection";
- }
- enum "gpon" {
- value 250;
- description
- "Gigabit-capable passive optical networks (G-PON) as per
- ITU-T G.948";
- }
- enum "vdsl2" {
- value 251;
- description
- "Very high speed digital subscriber line Version 2
- (as per ITU-T Recommendation G.993.2)";
- reference
- "RFC 5650 - Definitions of Managed Objects for Very High
- Speed Digital Subscriber Line 2 (VDSL2)";
- }
- enum "capwapDot11Profile" {
- value 252;
- description
- "WLAN Profile Interface";
- reference
- "RFC 5834 - Control and Provisioning of Wireless Access
- Points (CAPWAP) Protocol Binding MIB for
- IEEE 802.11";
- }
- enum "capwapDot11Bss" {
- value 253;
- description
- "WLAN BSS Interface";
- reference
- "RFC 5834 - Control and Provisioning of Wireless Access
- Points (CAPWAP) Protocol Binding MIB for
- IEEE 802.11";
- }
- enum "capwapWtpVirtualRadio" {
- value 254;
- description
- "WTP Virtual Radio Interface";
- reference
- "RFC 5833 - Control and Provisioning of Wireless Access
- Points (CAPWAP) Protocol Base MIB";
- }
- enum "bits" {
- value 255;
- description
- "bitsport";
- }
- enum "docsCableUpstreamRfPort" {
- value 256;
- description
- "DOCSIS CATV Upstream RF Port";
- }
- enum "cableDownstreamRfPort" {
- value 257;
- description
- "CATV downstream RF port";
- }
- enum "vmwareVirtualNic" {
- value 258;
- description
- "VMware Virtual Network Interface";
- }
- enum "ieee802154" {
- value 259;
- description
- "IEEE 802.15.4 WPAN interface";
- reference
- "IEEE 802.15.4-2006";
- }
- enum "otnOdu" {
- value 260;
- description
- "OTN Optical Data Unit";
- }
- enum "otnOtu" {
- value 261;
- description
- "OTN Optical channel Transport Unit";
- }
- enum "ifVfiType" {
- value 262;
- description
- "VPLS Forwarding Instance Interface Type";
- }
- enum "g9981" {
- value 263;
- description
- "G.998.1 bonded interface";
- }
- enum "g9982" {
- value 264;
- description
- "G.998.2 bonded interface";
- }
- enum "g9983" {
- value 265;
- description
- "G.998.3 bonded interface";
- }
- enum "aluEpon" {
- value 266;
- description
- "Ethernet Passive Optical Networks (E-PON)";
- }
- enum "aluEponOnu" {
- value 267;
- description
- "EPON Optical Network Unit";
- }
- enum "aluEponPhysicalUni" {
- value 268;
- description
- "EPON physical User to Network interface";
- }
- enum "aluEponLogicalLink" {
- value 269;
- description
- "The emulation of a point-to-point link over the EPON
- layer";
- }
- enum "aluGponOnu" {
- value 270;
- description
- "GPON Optical Network Unit";
- reference
- "ITU-T G.984.2";
- }
- enum "aluGponPhysicalUni" {
- value 271;
- description
- "GPON physical User to Network interface";
- reference
- "ITU-T G.984.2";
- }
- enum "vmwareNicTeam" {
- value 272;
- description
- "VMware NIC Team";
- }
- // value 273 reserved by IANA
- }
- description
- "This data type is used as the syntax of the 'type'
- leaf in the 'interface' list in the YANG module
- ietf-interface.
-
- The definition of this typedef with the
- addition of newly assigned values is published
- periodically by the IANA, in either the Assigned
- Numbers RFC, or some derivative of it specific to
- Internet Network Management number assignments. (The
- latest arrangements can be obtained by contacting the
- IANA.)
-
- Requests for new values should be made to IANA via
- email (iana&iana.org).";
- reference
- "IANA ifType definitions registry.
- <http://www.iana.org/assignments/smi-numbers>";
- }
-}
\ No newline at end of file
+++ /dev/null
-module ietf-interfaces {
-
- namespace "urn:ietf:params:xml:ns:yang:ietf-interfaces";
- prefix if;
-
- import ietf-yang-types {
- prefix yang;
- }
- import iana-if-type {
- prefix ianaift;
- }
-
- 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: Martin Bjorklund
- <mailto:mbj@tail-f.com>";
-
- description
- "This module contains a collection of YANG definitions for
- managing network interfaces.
-
- 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 XXXX; see
- the RFC itself for full legal notices.";
-
- // RFC Ed.: replace XXXX with actual RFC number and remove this
- // note.
-
- // RFC Ed.: update the date below with the date of RFC publication
- // and remove this note.
- revision 2013-07-04 {
- description
- "Initial revision.";
- reference
- "RFC XXXX: A YANG Data Model for Interface Management";
- }
-
- /* Typedefs */
-
- typedef interface-ref {
- type leafref {
- path "/if:interfaces/if:interface/if:name";
- }
- description
- "This type is used by data models that need to reference
- configured interfaces.";
- }
-
- typedef interface-state-ref {
- type leafref {
- path "/if:interfaces-state/if:interface/if:name";
- }
- description
- "This type is used by data models that need to reference
- the operationally present interfaces.";
- }
-
- /* Features */
-
- feature arbitrary-names {
- description
- "This feature indicates that the device allows user-controlled
- interfaces to be named arbitrarily.";
- }
-
- feature pre-provisioning {
- description
- "This feature indicates that the device supports
- pre-provisioning of interface configuration, i.e., it is
- possible to configure an interface whose physical interface
- hardware is not present on the device.";
- }
-
- feature if-mib {
- description
- "This feature indicates that the device implements IF-MIB.";
- reference
- "RFC 2863: The Interfaces Group MIB";
- }
-
- /* Data nodes */
-
- container interfaces {
- description
- "Interface configuration parameters.";
-
- list interface {
- key "name";
-
- description
- "The list of configured interfaces on the device.
-
- The operational state of an interface is available in the
- /interfaces-state/interface list. If the configuration of a
- system-controlled interface cannot be used by the system
- (e.g., the interface hardware present does not match the
- interface type), then the configuration is not applied to
- the system-controlled interface shown in the
- /interfaces-state/interface list. If the the configuration
- of a user-controlled interface cannot be used by the system,
- the configured interface is not instantiated in the
- /interfaces-state/interface list.";
-
- leaf name {
- type string;
- description
- "The name of the interface.
-
- A device MAY restrict the allowed values for this leaf,
- possibly depending on the type of the interface.
-
- For system-controlled interfaces, this leaf is the
- device-specific name of the interface. The 'config false'
- list /interfaces-state/interface contains the currently
- existing interfaces on the device.
-
- If a client tries to create configuration for a
- system-controlled interface that is not present in the
- /interfaces-state/interface list, the server MAY reject
- the request, if the implementation does not support
- pre-provisioning of interfaces, or if the name refers to
- an interface that can never exist in the system. A
- NETCONF server MUST reply with an rpc-error with the
- error-tag 'invalid-value' in this case.
-
- If the device supports pre-provisioning of interface
- configuration, the feature 'pre-provisioning' is
- advertised.
-
- If the device allows arbitrarily named user-controlled
- interfaces, the feature 'arbitrary-names' is advertised.
-
- When a configured user-controlled interface is created by
- the system, it is instantiated with the same name in the
- /interface-state/interface list. Since the name in that
- list MAY be mapped to ifName by an implementation, such an
- implementation MUST restrict the allowed values for this
- leaf so that it matches the restrictions of ifName.
-
- If a NETCONF server that implements this restriction is
- sent a value that doesn't match the restriction, it MUST
- reply with an rpc-error with the error-tag
- 'invalid-value'.";
- }
-
- leaf description {
- type string;
- description
- "A textual description of the interface.
-
- This leaf MAY be mapped to ifAlias by an implementation.
- Such an implementation MUST restrict the allowed values
- for this leaf so that it matches the restrictions of
- ifAlias.
-
- If a NETCONF server that implements this restriction is
- sent a value that doesn't match the restriction, it MUST
- reply with an rpc-error with the error-tag
- 'invalid-value'.
-
- Since ifAlias is defined to be stored in non-volatile
- storage, the MIB implementation MUST map ifAlias to the
- value of 'description' in the persistently stored
- datastore.
-
- Specifically, if the device supports ':startup', when
- ifAlias is read the device MUST return the value of
- 'description' in the 'startup' datastore, and when it is
- written, it MUST be written to the 'running' and 'startup'
- datastores. Note that it is up to the implementation if
- it modifies this single leaf in 'startup', or if it
- performs an implicit copy-config from 'running' to
- 'startup'.
-
- If the device does not support ':startup', ifAlias MUST
- be mapped to the 'description' leaf in the 'running'
- datastore.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifAlias";
- }
-
- leaf type {
- type ianaift:iana-if-type;
- mandatory true;
- description
- "The type of the interface.
-
- When an interface entry is created, a server MAY
- initialize the type leaf with a valid value, e.g., if it
- is possible to derive the type from the name of the
- interface.
-
- If a client tries to set the type of an interface to a
- value that can never be used by the system, e.g., if the
- type is not supported or if the type does not match the
- name of the interface, the server MUST reject the request.
- A NETCONF server MUST reply with an rpc-error with the
- error-tag 'invalid-value' in this case.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifType";
- }
-
- leaf enabled {
- type boolean;
- default "true";
- description
- "This leaf contains the configured, desired state of the
- interface.
-
- Systems that implement the IF-MIB use the value of this
- leaf in the 'running' datastore to set
- IF-MIB.ifAdminStatus to 'up' or 'down' after an ifEntry
- has been initialized, as described in RFC 2863.
-
- Changes in this leaf in the 'running' datastore are
- reflected in ifAdminStatus, but if ifAdminStatus is
- changed over SNMP, this leaf is not affected.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifAdminStatus";
- }
-
- leaf link-up-down-trap-enable {
- if-feature if-mib;
- type enumeration {
- enum enabled {
- value 1;
- }
- enum disabled {
- value 2;
- }
- }
- description
- "Controls whether linkUp/linkDown SNMP notifications
- should be generated for this interface.
-
- If this node is not configured, the value 'enabled' is
- operationally used by the server for interfaces which do
- not operate on top of any other interface (i.e., there are
- no 'lower-layer-if' entries), and 'disabled' otherwise.";
- reference
- "RFC 2863: The Interfaces Group MIB -
- ifLinkUpDownTrapEnable";
- }
- }
- }
-
- container interfaces-state {
- config false;
- description
- "Data nodes for the operational state of interfaces.";
-
- list interface {
- key "name";
-
- description
- "The list of interfaces on the device.
-
- System-controlled interfaces created by the system are
- always present in this list, whether they are configured or
- not.";
-
- leaf name {
- type string;
- description
- "The name of the interface.
-
- This leaf MAY be mapped to ifName by an implementation.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifName";
- }
-
- leaf type {
- type ianaift:iana-if-type;
- mandatory true;
- description
- "The type of the interface.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifType";
- }
-
- leaf admin-status {
- if-feature if-mib;
- type enumeration {
- enum up {
- value 1;
- description
- "Ready to pass packets.";
- }
- enum down {
- value 2;
- description
- "Not ready to pass packets and not in some test mode.";
- }
- enum testing {
- value 3;
- description
- "In some test mode.";
- }
- }
- mandatory true;
- description
- "The desired state of the interface.
-
- This leaf has the same read semantics as ifAdminStatus.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifAdminStatus";
- }
-
- leaf oper-status {
- type enumeration {
- enum up {
- value 1;
- description
- "Ready to pass packets.";
- }
- enum down {
- value 2;
- description
- "The interface does not pass any packets.";
- }
- enum testing {
- value 3;
- description
- "In some test mode. No operational packets can
- be passed.";
- }
- enum unknown {
- value 4;
- description
- "Status cannot be determined for some reason.";
- }
- enum dormant {
- value 5;
- description
- "Waiting for some external event.";
- }
- enum not-present {
- value 6;
- description
- "Some component (typically hardware) is missing.";
- }
- enum lower-layer-down {
- value 7;
- description
- "Down due to state of lower-layer interface(s).";
- }
- }
- mandatory true;
- description
- "The current operational state of the interface.
-
- This leaf has the same semantics as ifOperStatus.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifOperStatus";
- }
-
- leaf last-change {
- type yang:date-and-time;
- description
- "The time the interface entered its current operational
- state. If the current state was entered prior to the
- last re-initialization of the local network management
- subsystem, then this node is not present.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifLastChange";
- }
-
- leaf if-index {
- if-feature if-mib;
- type int32 {
- range "1..2147483647";
- }
- mandatory true;
- description
- "The ifIndex value for the ifEntry represented by this
- interface.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifIndex";
- }
-
- leaf phys-address {
- type yang:phys-address;
- description
- "The interface's address at its protocol sub-layer. For
- example, for an 802.x interface, this object normally
- contains a MAC address. The interface's media-specific
- modules must define the bit and byte ordering and the
- format of the value of this object. For interfaces that do
- not have such an address (e.g., a serial line), this node
- is not present.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifPhysAddress";
- }
-
- leaf-list higher-layer-if {
- type interface-state-ref;
- description
- "A list of references to interfaces layered on top of this
- interface.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifStackTable";
- }
-
- leaf-list lower-layer-if {
- type interface-state-ref;
- description
- "A list of references to interfaces layered underneath this
- interface.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifStackTable";
- }
-
- leaf speed {
- type yang:gauge64;
- units "bits / second";
- description
- "An estimate of the interface's current bandwidth in bits
- per second. For interfaces that do not vary in
- bandwidth or for those where no accurate estimation can
- be made, this node should contain the nominal bandwidth.
- For interfaces that have no concept of bandwidth, this
- node is not present.";
- reference
- "RFC 2863: The Interfaces Group MIB -
- ifSpeed, ifHighSpeed";
- }
-
- container statistics {
- description
- "A collection of interface-related statistics objects.";
-
- leaf discontinuity-time {
- type yang:date-and-time;
- mandatory true;
- description
- "The time on the most recent occasion at which any one or
- more of this interface's counters suffered a
- discontinuity. If no such discontinuities have occurred
- since the last re-initialization of the local management
- subsystem, then this node contains the time the local
- management subsystem re-initialized itself.";
- }
-
- leaf in-octets {
- type yang:counter64;
- description
- "The total number of octets received on the interface,
- including framing characters.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifHCInOctets";
- }
- leaf in-unicast-pkts {
- type yang:counter64;
- description
- "The number of packets, delivered by this sub-layer to a
- higher (sub-)layer, which were not addressed to a
- multicast or broadcast address at this sub-layer.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifHCInUcastPkts";
- }
- leaf in-broadcast-pkts {
- type yang:counter64;
- description
- "The number of packets, delivered by this sub-layer to a
- higher (sub-)layer, which were addressed to a broadcast
- address at this sub-layer.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB -
- ifHCInBroadcastPkts";
- }
- leaf in-multicast-pkts {
- type yang:counter64;
- description
- "The number of packets, delivered by this sub-layer to a
- higher (sub-)layer, which were addressed to a multicast
- address at this sub-layer. For a MAC layer protocol,
- this includes both Group and Functional addresses.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB -
- ifHCInMulticastPkts";
- }
- leaf in-discards {
- type yang:counter32;
- description
- "The number of inbound packets which were chosen to be
- discarded even though no errors had been detected to
- prevent their being deliverable to a higher-layer
- protocol. One possible reason for discarding such a
- packet could be to free up buffer space.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifInDiscards";
- }
- leaf in-errors {
- type yang:counter32;
- description
- "For packet-oriented interfaces, the number of inbound
- packets that contained errors preventing them from being
- deliverable to a higher-layer protocol. For character-
- oriented or fixed-length interfaces, the number of
- inbound transmission units that contained errors
- preventing them from being deliverable to a higher-layer
- protocol.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifInErrors";
- }
- leaf in-unknown-protos {
- type yang:counter32;
- description
- "For packet-oriented interfaces, the number of packets
- received via the interface which were discarded because
- of an unknown or unsupported protocol. For
- character-oriented or fixed-length interfaces that
- support protocol multiplexing the number of transmission
- units received via the interface which were discarded
- because of an unknown or unsupported protocol. For any
- interface that does not support protocol multiplexing,
- this counter is not present.
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifInUnknownProtos";
- }
-
- leaf out-octets {
- type yang:counter64;
- description
- "The total number of octets transmitted out of the
- interface, including framing characters.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifHCOutOctets";
- }
- leaf out-unicast-pkts {
- type yang:counter64;
- description
- "The total number of packets that higher-level protocols
- requested be transmitted, and which were not addressed
- to a multicast or broadcast address at this sub-layer,
- including those that were discarded or not sent.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifHCOutUcastPkts";
- }
- leaf out-broadcast-pkts {
- type yang:counter64;
- description
- "The total number of packets that higher-level protocols
- requested be transmitted, and which were addressed to a
- broadcast address at this sub-layer, including those
- that were discarded or not sent.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB -
- ifHCOutBroadcastPkts";
- }
- leaf out-multicast-pkts {
- type yang:counter64;
- description
- "The total number of packets that higher-level protocols
- requested be transmitted, and which were addressed to a
- multicast address at this sub-layer, including those
- that were discarded or not sent. For a MAC layer
- protocol, this includes both Group and Functional
- addresses.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB -
- ifHCOutMulticastPkts";
- }
- leaf out-discards {
- type yang:counter32;
- description
- "The number of outbound packets which were chosen to be
- discarded even though no errors had been detected to
- prevent their being transmitted. One possible reason
- for discarding such a packet could be to free up buffer
- space.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifOutDiscards";
- }
- leaf out-errors {
- type yang:counter32;
- description
- "For packet-oriented interfaces, the number of outbound
- packets that could not be transmitted because of errors.
- For character-oriented or fixed-length interfaces, the
- number of outbound transmission units that could not be
- transmitted because of errors.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifOutErrors";
- }
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-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 XXXX; see
- the RFC itself for full legal notices.";
-
- revision 2013-05-16 {
- description
- "This revision adds the following new data types:
- - yang-identifier
- - hex-string
- - uuid
- - dotted-quad";
- reference
- "RFC XXXX: 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-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)";
- }
-
- 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 in RFC 6020, page 163.
- 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 lower-case or upper-case character
- sequence 'xml'.";
- reference
- "RFC 6020: YANG - A Data Modeling Language for the Network
- Configuration Protocol (NETCONF)";
- }
-
- /*** 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";
- }
-
- /*** 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
+++ /dev/null
-module sal-remote {
-
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote";
- prefix "sal-remote";
-
-
- organization "Cisco Systems, Inc.";
- contact "Martin Bobak <mbobak@cisco.com>";
-
- description
- "This module contains the definition of methods related to
- sal remote model.
-
- Copyright (c)2013 Cisco Systems, Inc. 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";
-
- revision "2014-01-14" {
- description
- "Initial revision";
- }
-
-
- typedef q-name {
- type string;
- reference
- "http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#QName";
- }
-
- rpc create-data-change-event-subscription {
- input {
- leaf path {
- type instance-identifier;
- description "Subtree path. ";
- }
- }
- output {
- leaf stream-name {
- type string;
- description "Notification stream name.";
- }
- }
- }
-
- notification data-changed-notification {
- description "Data change notification.";
- list data-change-event {
- key path;
- leaf path {
- type instance-identifier;
- }
- leaf store {
- type enumeration {
- enum config;
- enum operation;
- }
- }
- leaf operation {
- type enumeration {
- enum created;
- enum updated;
- enum deleted;
- }
- }
- anyxml data{
- description "DataObject ";
- }
- }
- }
-
- rpc create-notification-stream {
- input {
- leaf-list notifications {
- type q-name;
- description "Notification QNames";
- }
- }
- output {
- leaf notification-stream-identifier {
- type string;
- description "Unique notification stream identifier, in which notifications will be propagated";
- }
- }
- }
-
- rpc begin-transaction{
- output{
- anyxml data-modification-transaction{
- description "DataModificationTransaction xml";
- }
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-module simple-nodes {
- yang-version 1;
- namespace "urn:opendaylight:simple-nodes";
- prefix "sn";
-
- description
- "test file containing yang data nodes";
-
- revision "2013-07-30" {
- description
- "Initial revision.";
- reference "will be defined";
- }
-
- container users {
- leaf user {
- type string;
- }
-
- leaf group {
- type string;
- }
- }
-
- list user {
- key "name class";
- leaf name {
- type string;
- }
- leaf full-name {
- type string;
- }
- leaf class {
- type string;
- }
- }
-
- list userWithoutClass {
- key "name";
- leaf name {
- type string;
- }
- leaf full-name {
- type string;
- }
- container inner-container {
- leaf inner-list {
- type uint16;
- }
- }
- }
-
- container food {
- choice snack {
- case sports-arena {
- leaf pretzel {
- type string;
- }
- leaf beer {
- type string;
- }
- container nonalcoholic {
- leaf beer {
- type string;
- }
- }
- }
- case late-night {
- leaf chocolate {
- type enumeration {
- enum dark;
- enum milk;
- enum first-available;
- }
- }
- }
- }
- }
-
-}
+++ /dev/null
-module subscribe-to-notification {
-
- yang-version 1;
- namespace "subscribe:to:notification";
- prefix "subs-to-notifi";
-
- description
- "Added input parameters to rpc create-data-change-event-subscription and to create-notification-stream";
-
- revision "2016-10-28" {
- }
-
- container "notifi"{
- leaf "location"{
- type string;
- }
- }
-}
+++ /dev/null
- module toaster {
-
- yang-version 1;
-
- namespace
- "http://netconfcentral.org/ns/toaster";
-
- prefix toast;
-
- organization "Netconf Central";
-
- contact
- "Andy Bierman <andy@netconfcentral.org>";
-
- description
- "YANG version of the TOASTER-MIB.";
-
- revision "2009-11-20" {
- description
- "Toaster module in progress.";
- }
-
-
- identity toast-type {
- description
- "Base for all bread types supported by the toaster.
- New bread types not listed here nay be added in the
- future.";
- }
-
- identity white-bread {
- base toast:toast-type;
- description "White bread.";
- }
-
- identity wheat-bread {
- base toast-type;
- description "Wheat bread.";
- }
-
- identity wonder-bread {
- base toast-type;
- description "Wonder bread.";
- }
-
- identity frozen-waffle {
- base toast-type;
- description "Frozen waffle.";
- }
-
- identity frozen-bagel {
- base toast-type;
- description "Frozen bagel.";
- }
-
- identity hash-brown {
- base toast-type;
- description "Hash browned potatos.";
- }
-
- typedef DisplayString {
- type string {
- length "0 .. 255";
- }
- description
- "YANG version of the SMIv2 DisplayString TEXTUAL-CONVENTION.";
- reference
- "RFC 2579, section 2.";
-
- }
-
- container toaster {
- presence
- "Indicates the toaster service is available";
- description
- "Top-level container for all toaster database objects.";
- leaf toasterManufacturer {
- type DisplayString;
- config false;
- mandatory true;
- description
- "The name of the toaster's manufacturer. For instance,
- Microsoft Toaster.";
- }
-
- leaf toasterModelNumber {
- type DisplayString;
- config false;
- mandatory true;
- description
- "The name of the toaster's model. For instance,
- Radiant Automatic.";
- }
-
- leaf toasterStatus {
- type enumeration {
- enum "up" {
- value 1;
- description
- "The toaster knob position is up.
- No toast is being made now.";
- }
- enum "down" {
- value 2;
- description
- "The toaster knob position is down.
- Toast is being made now.";
- }
- }
- config false;
- mandatory true;
- description
- "This variable indicates the current state of
- the toaster.";
- }
- } // container toaster
-
- rpc make-toast {
- description
- "Make some toast.
- The toastDone notification will be sent when
- the toast is finished.
- An 'in-use' error will be returned if toast
- is already being made.
- A 'resource-denied' error will be returned
- if the toaster service is disabled.";
- input {
- leaf toasterDoneness {
- type uint32 {
- range "1 .. 10";
- }
- default '5';
- description
- "This variable controls how well-done is the
- ensuing toast. It should be on a scale of 1 to 10.
- Toast made at 10 generally is considered unfit
- for human consumption; toast made at 1 is warmed
- lightly.";
- }
-
- leaf toasterToastType {
- type identityref {
- base toast:toast-type;
- }
- default 'wheat-bread';
- description
- "This variable informs the toaster of the type of
- material that is being toasted. The toaster
- uses this information, combined with
- toasterDoneness, to compute for how
- long the material must be toasted to achieve
- the required doneness.";
- }
- }
- } // rpc make-toast
-
- rpc testOutput {
- output {
- leaf textOut {
- type string;
- }
- }
- }
-
- rpc cancel-toast {
- description
- "Stop making toast, if any is being made.
- A 'resource-denied' error will be returned
- if the toaster service is disabled.";
- } // rpc cancel-toast
-
- notification toastDone {
- description
- "Indicates that the toast in progress has completed.";
- leaf toastStatus {
- type enumeration {
- enum "done" {
- value 0;
- description "The toast is done.";
- }
- enum "cancelled" {
- value 1;
- description
- "The toast was cancelled.";
- }
- enum "error" {
- value 2;
- description
- "The toaster service was disabled or
- the toaster is broken.";
- }
- }
- description
- "Indicates the final toast status";
- }
- } // notification toastDone
- } // module toaster
+++ /dev/null
-module iid-value-module {
- namespace "iid:value:module";
-
- prefix "iidvm";
- revision 2016-09-12 {
- }
-
- container cont-iid {
- list iid-list{
- key "iid-leaf";
- leaf iid-leaf{
- type instance-identifier;
- }
- }
-
- list values-iid{
- key "value-iid";
- leaf value-iid{
- type string;
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "ietf-yang-patch:yang-patch" : {
- "patch-id" : "Test merge operation",
- "comment" : "This is test patch for merge operation on container",
- "edit" : [
- {
- "edit-id": "edit1",
- "operation": "create",
- "target": "/",
- "value": {
- "patch-cont": {
- "my-list1": [
- {
- "name": "my-list1 - A",
- "my-leaf11": "I am leaf11-0",
- "my-leaf12": "I am leaf12-1"
- },
- {
- "name": "my-list1 - B",
- "my-leaf11": "I am leaf11-0",
- "my-leaf12": "I am leaf12-1"
- }
- ]
- }
- }
- },
- {
- "edit-id": "edit2",
- "operation": "merge",
- "target": "/",
- "value": {
- "patch-cont": {
- "my-list1": {
- "name": "my-list1 - Merged",
- "my-leaf11": "I am leaf11-0",
- "my-leaf12": "I am leaf12-1"
- }
- }
- }
- }
- ]
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "ietf-yang-patch:yang-patch" : {
- "patch-id" : "Test merge operation",
- "comment" : "This is test patch for merge operation on list",
- "edit" : [
- {
- "edit-id": "edit1",
- "operation": "replace",
- "target": "/instance-identifier-patch-module:my-list2[instance-identifier-patch-module:name='my-leaf20']",
- "value": {
- "my-list2": {
- "name": "my-leaf20",
- "my-leaf21": "I am leaf21-0",
- "my-leaf22": "I am leaf22-0"
- }
- }
- },
- {
- "edit-id": "edit2",
- "operation": "merge",
- "target": "/instance-identifier-patch-module:my-list2[instance-identifier-patch-module:name='my-leaf21']",
- "value": {
- "my-list2": {
- "name": "my-leaf21",
- "my-leaf21": "I am leaf21-1",
- "my-leaf22": "I am leaf22-1"
- }
- }
- }
- ]
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "ietf-yang-patch:yang-patch" : {
-
- "patch-id" : "test-patch",
- "comment" : "this is test patch for simple leaf value",
- "edit" : [
- {
- "edit-id": "edit1",
- "operation": "replace",
- "target": "/instance-identifier-patch-module:my-list2[instance-identifier-patch-module:name='my-leaf20']/instance-identifier-patch-module:name",
- "value": {
- "name": "my-leaf20"
- }
- }
- ]
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "ietf-yang-patch:yang-patch" : {
-
- "patch-id" : "test-patch",
- "comment" : "this is test patch",
- "edit" : [
- {
- "edit-id": "edit1",
- "operation": "replace",
- "target": "/instance-identifier-patch-module:my-list2[instance-identifier-patch-module:name='my-leaf20']",
- "value": {
- "my-list2": {
- "name": "my-leaf20",
- "my-leaf21": "I am leaf21-0",
- "my-leaf22": "I am leaf22-0"
- }
- }
- },
-
- {
- "edit-id": "edit2",
- "operation": "replace",
- "target": "/instance-identifier-patch-module:my-list2[instance-identifier-patch-module:name='my-leaf20']",
- "value": {
- "my-list2": {
- "name": "my-leaf20",
- "my-leaf21": "I am leaf21-1",
- "my-leaf22": "I am leaf22-1",
- "my-leaf-list": ["listelement"]
- }
- }
- }
- ]
- }
-}
+++ /dev/null
-{
- "ietf-yang-patch:yang-patch" : {
-
- "patch-id" : "test-patch",
- "comment" : "Test to create and replace data in container directly using / sign as a target",
- "edit" : [
- {
- "edit-id": "edit1",
- "operation": "create",
- "target": "/",
- "value": {
- "patch-cont": {
- "my-list1": [
- {
- "name": "my-list1 - A",
- "my-leaf11": "I am leaf11-0",
- "my-leaf12": "I am leaf12-1"
- },
- {
- "name": "my-list1 - B",
- "my-leaf11": "I am leaf11-0",
- "my-leaf12": "I am leaf12-1"
- }
- ]
- }
- }
- },
- {
- "edit-id": "edit2",
- "operation": "replace",
- "target": "/",
- "value": {
- "patch-cont": {
- "my-list1": {
- "name": "my-list1 - Replacing",
- "my-leaf11": "I am leaf11-0",
- "my-leaf12": "I am leaf12-1"
- }
- }
- }
- }
- ]
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "ietf-yang-patch:yang-patch" : {
- "patch-id" : "test-patch",
- "comment" : "this is test patch",
- "edit" : [
- {
- "edit-id": "edit1",
- "value": {
- "my-list2": [
- {
- "name": "my-leaf20",
- "my-leaf21": "I am leaf20"
- },
- {
- "name": "my-leaf21",
- "my-leaf21": "I am leaf21-1",
- "my-leaf22": "I am leaf21-2"
- }
- ]
- },
- "target": "/instance-identifier-patch-module:my-list2[instance-identifier-patch-module:name='my-leaf20']",
- "operation": "create"
- },
- {
- "edit-id": "edit2",
- "operation": "delete",
- "target": "/instance-identifier-patch-module:my-list2[instance-identifier-patch-module:name='my-leaf20']"
- }
- ]
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "ietf-yang-patch:yang-patch" : {
- "patch-id" : "test-patch",
- "comment" : "this is test patch",
- "edit" : [
- {
- "edit-id": "edit1",
- "target": "/instance-identifier-patch-module:my-list2[instance-identifier-patch-module:name='my-leaf20']",
- "operation": "create"
- }
- ]
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "ietf-yang-patch:yang-patch" : {
- "patch-id" : "test-patch",
- "comment" : "this is test patch",
- "edit" : [
- {
- "edit-id": "edit2",
- "operation": "delete",
- "target": "/instance-identifier-patch-module:my-list2[instance-identifier-patch-module:name='my-leaf20']",
- "value": {
- "my-list2": [
- {
- "name": "my-leaf20"
- }
- ]
- }
- }
- ]
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "augment-module:case-choice-case-container1": {
- "augment-module:case-choice-case-leaf1": "stryng"
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "augment-module:cont-augment": {
- "augment-module:leaf1": "stryng"
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "instance-identifier-module:cont1": {
- "augment-module-leaf-list:lf11" : "/instance-identifier-module:cont/instance-identifier-module:cont1/augment-module-leaf-list:lflst11[.=\"lflst11_1\"]"
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "instance-identifier-module:cont": {
- "cont1": {
- "augment-module:lst11": [
- {
- "keyvalue111":"value1",
- "keyvalue112":"value2",
- "augment-augment-module:lf111":"/instance-identifier-module:cont/instance-identifier-module:cont1/augment-module:lst11[augment-module:keyvalue111=\"value1\"][augment-module:keyvalue112=\"value2\"]/augment-augment-module:lf112",
- "augment-augment-module:lf112":"lf112 value"
- }
- ]
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "instance-identifier-module:cont": {
- "cont1": {
- "augment-module-leaf-list:lf11" : "/instance-identifier-module:cont/instance-identifier-module:cont1/augment-module-leaf-list:lflst11[.=\"lflst11_1\"]"
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-<!--
- ~ 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
- -->
-
-<cont1 xmlns="instance:identifier:module"/>
+++ /dev/null
-<!--
- ~ 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
- -->
-
-<foo-bar-container xmlns="bar:module">
-</foo-bar-container>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ 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
- -->
-
-<foo-bar-container xmlns="foo:module">
-</foo-bar-container>
\ No newline at end of file
+++ /dev/null
-<yang-patch xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-patch">
- <patch-id>test-patch</patch-id>
- <comment>this is test patch</comment>
- <edit>
- <edit-id>edit1</edit-id>
- <operation>create</operation>
- <target>/my-list2</target>
- <value>
- <my-list2 xmlns="instance:identifier:patch:module">
- <name>my-leaf20</name>
- <my-leaf21>I am leaf21-0</my-leaf21>
- <my-leaf22>I am leaf22-0</my-leaf22>
- </my-list2>
- </value>
- </edit>
- <edit>
- <edit-id>edit2</edit-id>
- <operation>create</operation>
- <target>/my-list2</target>
- <value>
- <my-list2 xmlns="instance:identifier:patch:module">
- <name>my-leaf21</name>
- <my-leaf21>I am leaf21-1</my-leaf21>
- <my-leaf22>I am leaf22-1</my-leaf22>
- </my-list2>
- </value>
- </edit>
-</yang-patch>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ 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
- -->
-<yang-patch xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-patch">
- <patch-id>test-patch</patch-id>
- <comment>Test patch with absolute target path</comment>
- <edit>
- <edit-id>edit1</edit-id>
- <operation>create</operation>
- <target>/instance-identifier-patch-module:patch-cont/my-list1/leaf1/my-list2</target>
- <value>
- <my-list2 xmlns="instance:identifier:patch:module">
- <name>my-leaf20</name>
- <my-leaf21>I am leaf21-0</my-leaf21>
- <my-leaf22>I am leaf22-0</my-leaf22>
- </my-list2>
- </value>
- </edit>
- <edit>
- <edit-id>edit2</edit-id>
- <operation>create</operation>
- <target>/instance-identifier-patch-module:patch-cont/my-list1/leaf1/my-list2</target>
- <value>
- <my-list2 xmlns="instance:identifier:patch:module">
- <name>my-leaf21</name>
- <my-leaf21>I am leaf21-1</my-leaf21>
- <my-leaf22>I am leaf22-1</my-leaf22>
- </my-list2>
- </value>
- </edit>
-</yang-patch>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ 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
- -->
-<yang-patch xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-patch">
- <patch-id>test-patch</patch-id>
- <comment>Test to create and replace data in container directly using / sign as a target</comment>
- <edit>
- <edit-id>edit1</edit-id>
- <operation>create</operation>
- <target>/</target>
- <value>
- <patch-cont xmlns="instance:identifier:patch:module">
- <my-list1>
- <name>my-list1 - A</name>
- <my-leaf11>I am leaf11-0</my-leaf11>
- <my-leaf12>I am leaf12-1</my-leaf12>
- </my-list1>
- <my-list1>
- <name>my-list1 - B</name>
- <my-leaf11>I am leaf11-0</my-leaf11>
- <my-leaf12>I am leaf12-1</my-leaf12>
- </my-list1>
- </patch-cont>
- </value>
- </edit>
- <edit>
- <edit-id>edit2</edit-id>
- <operation>replace</operation>
- <target>/</target>
- <value>
- <patch-cont xmlns="instance:identifier:patch:module">
- <my-list1>
- <name>my-list1 - Replacing</name>
- <my-leaf11>I am leaf11-0</my-leaf11>
- <my-leaf12>I am leaf12-1</my-leaf12>
- </my-list1>
- </patch-cont>
- </value>
- </edit>
-</yang-patch>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ 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
- -->
-<yang-patch xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-patch">
- <patch-id>Test merge operation</patch-id>
- <comment>This is test patch for merge operation on container</comment>
- <edit>
- <edit-id>edit1</edit-id>
- <operation>create</operation>
- <target>/</target>
- <value>
- <patch-cont xmlns="instance:identifier:patch:module">
- <my-list1>
- <name>my-list1 - A</name>
- <my-leaf11>I am leaf11-0</my-leaf11>
- <my-leaf12>I am leaf12-1</my-leaf12>
- </my-list1>
- <my-list1>
- <name>my-list1 - B</name>
- <my-leaf11>I am leaf11-0</my-leaf11>
- <my-leaf12>I am leaf12-1</my-leaf12>
- </my-list1>
- </patch-cont>
- </value>
- </edit>
- <edit>
- <edit-id>edit2</edit-id>
- <operation>merge</operation>
- <target>/</target>
- <value>
- <patch-cont xmlns="instance:identifier:patch:module">
- <my-list1>
- <name>my-list1 - Merged</name>
- <my-leaf11>I am leaf11-0</my-leaf11>
- <my-leaf12>I am leaf12-1</my-leaf12>
- </my-list1>
- </patch-cont>
- </value>
- </edit>
-</yang-patch>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ 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
- -->
-<yang-patch xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-patch">
- <patch-id>Test merge operation</patch-id>
- <comment>This is test patch for merge operation on list</comment>
- <edit>
- <edit-id>edit1</edit-id>
- <operation>replace</operation>
- <target>/my-list2</target>
- <value>
- <my-list2 xmlns="instance:identifier:patch:module">
- <name>my-leaf20</name>
- <my-leaf21>I am leaf21-0</my-leaf21>
- <my-leaf22>I am leaf22-0</my-leaf22>
- </my-list2>
- </value>
- </edit>
- <edit>
- <edit-id>edit2</edit-id>
- <operation>merge</operation>
- <target>/my-list2</target>
- <value>
- <my-list2 xmlns="instance:identifier:patch:module">
- <name>my-leaf21</name>
- <my-leaf21>I am leaf21-1</my-leaf21>
- <my-leaf22>I am leaf22-1</my-leaf22>
- </my-list2>
- </value>
- </edit>
-</yang-patch>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ 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
- -->
-<yang-patch xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-patch">
- <patch-id>test-patch</patch-id>
- <comment>Test patch with missing value node for create operation</comment>
- <edit>
- <edit-id>edit1</edit-id>
- <operation>create</operation>
- <target>/my-list2</target>
- </edit>
-</yang-patch>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ 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
- -->
-<yang-patch xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-patch">
- <patch-id>test-patch</patch-id>
- <comment>Test patch with not allowed value node for delete operation</comment>
- <edit>
- <edit-id>edit1</edit-id>
- <operation>delete</operation>
- <target>/my-list2/my-leaf21</target>
- <value>
- <my-list2 xmlns="instance:identifier:patch:module">
- <name>my-leaf20</name>
- <my-leaf21>I am leaf21-0</my-leaf21>
- <my-leaf22>I am leaf22-0</my-leaf22>
- </my-list2>
- </value>
- </edit>
-</yang-patch>
\ No newline at end of file
+++ /dev/null
-<case-choice-case-container1 xmlns="augment:module">
- <case-choice-case-leaf1>stryng</case-choice-case-leaf1>
-</case-choice-case-container1>
\ No newline at end of file
+++ /dev/null
-<cont-augment xmlns="augment:module">
- <leaf1>stryng</leaf1>
-</cont-augment>
\ No newline at end of file
+++ /dev/null
-<cont1 xmlns="instance:identifier:module">
- <lflst11 xmlns="augment:module:leaf:list">lflst11_1</lflst11>
- <lflst11 xmlns="augment:module:leaf:list">lflst11_2</lflst11>
- <lflst11 xmlns="augment:module:leaf:list">lflst11_3</lflst11>
- <lf11 xmlns:a="instance:identifier:module" xmlns:b="augment:module:leaf:list" xmlns="augment:module:leaf:list">/a:cont/a:cont1/b:lflst11[.="lflst11_1"]</lf11>
-</cont1>
\ No newline at end of file
+++ /dev/null
-<cont xmlns="instance:identifier:module">
- <cont1>
- <lst11 xmlns="augment:module" xmlns:c="augment:augment:module">
- <keyvalue111>value1</keyvalue111>
- <keyvalue112>value2</keyvalue112>
- <lf111 xmlns="augment:augment:module" xmlns:a="instance:identifier:module" xmlns:b="augment:module" >/a:cont/a:cont1/b:lst11[b:keyvalue111="value1"][b:keyvalue112="value2"]/c:lf112</lf111>
- <lf112 xmlns="augment:augment:module">lf112 value</lf112>
- </lst11>
- </cont1>
-</cont>
+++ /dev/null
-<cont xmlns="instance:identifier:module">
- <cont1>
- <lflst11 xmlns="augment:module:leaf:list">lflst11_1</lflst11>
- <lflst11 xmlns="augment:module:leaf:list">lflst11_2</lflst11>
- <lflst11 xmlns="augment:module:leaf:list">lflst11_3</lflst11>
- <lf11 xmlns:a="instance:identifier:module" xmlns:b="augment:module:leaf:list" xmlns="augment:module:leaf:list">/a:cont/a:cont1/b:lflst11[.="lflst11_1"]</lf11>
- </cont1>
-</cont>
+++ /dev/null
-module augment-augment-module {
- namespace "augment:augment:module";
-
- prefix "aamodule";
-
- import augment-module {prefix amodule; revision-date 2014-01-17;}
- import instance-identifier-module {prefix imodule; revision-date 2014-01-17;}
-
- revision 2014-01-17 {
- }
-
- augment "/imodule:cont/imodule:cont1/amodule:lst11" {
- leaf lf111 {
- type instance-identifier;
- }
- leaf lf112 {
- type string;
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-module augment-module-leaf-list {
- namespace "augment:module:leaf:list";
-
- prefix "amodulelflst";
-
- import instance-identifier-module {prefix imodule; revision-date 2014-01-17;}
-
- revision 2014-01-27 {
- }
-
- augment "/imodule:cont/imodule:cont1" {
- leaf-list lflst11 {
- type string;
- }
- leaf lf11 {
- type instance-identifier;
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-module augment-module {
- namespace "augment:module";
-
- prefix "amodule";
-
- import instance-identifier-module {prefix imodule; revision-date 2014-01-17;}
-
- revision 2014-01-17 {
- }
-
- augment "/imodule:cont/imodule:cont1" {
- list lst11 {
- key "keyvalue111 keyvalue112";
- leaf keyvalue111 {
- type string;
- }
- leaf keyvalue112 {
- type string;
- }
- }
- }
-
- augment "/imodule:cont" {
- container cont-augment {
- leaf leaf1 {
- type string;
- }
- }
- }
-
- augment "/imodule:cont" {
- choice augment-choice1 {
- case case1 {
- container case-container1 {
- leaf case-leaf1 {
- type string;
- }
- }
- }
-
- case case2 {
- container case-container2 {
- leaf case-leaf2 {
- type string;
- }
- }
- }
- }
- }
-
- augment "/imodule:cont/augment-choice1/case1" {
- choice augment-choice2 {
- case case11 {
- container case-choice-case-container1 {
- leaf case-choice-case-leaf1 {
- type string;
- }
- }
- }
- }
- }
-
-}
+++ /dev/null
-module bar-module {
- namespace "bar:module";
-
- prefix "bar-module";
- revision 2016-09-29 {
- }
-
- /* This container has the same name as container in foo-module */
- container foo-bar-container {
- }
-}
\ No newline at end of file
+++ /dev/null
-module foo-module {
- namespace "foo:module";
-
- prefix "foo-module";
- revision 2016-09-29 {
- }
-
- /* This container has the same name as container in bar-module */
- container foo-bar-container {
- }
-}
\ No newline at end of file
+++ /dev/null
-module instance-identifier-module {
- namespace "instance:identifier:module";
-
- prefix "iimodule";
- revision 2014-01-17 {
- }
-
- container cont {
- container cont1 {
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-module instance-identifier-patch-module {
- namespace "instance:identifier:patch:module";
-
- prefix "iipmodule";
- revision 2015-11-21 {
- }
-
- container patch-cont {
- list my-list1 {
-
- description "PATCH /restconf/config/instance-identifier-patch-module:patch-cont/my-list1/leaf1";
-
- key name;
-
- leaf name {
- type string;
- }
-
- leaf my-leaf11 {
- type string;
- }
-
- leaf my-leaf12 {
- type string;
- }
-
- list my-list2 {
- key name;
-
- leaf name {
- type string;
- }
-
- leaf my-leaf21 {
- type string;
- }
-
- leaf my-leaf22 {
- type string;
- }
- leaf-list my-leaf-list {
- type string;
- }
- }
- }
- }
-}
+++ /dev/null
- 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)";
- }
-
- }
+++ /dev/null
-module ietf-restconf-monitoring {
- namespace "urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring";
- prefix "rcmon";
-
- import ietf-yang-types { prefix yang; }
- import ietf-inet-types { prefix inet; }
-
- organization
- "IETF NETCONF (Network Configuration) Working Group";
-
- contact
- "WG Web: <https://datatracker.ietf.org/wg/netconf/>
- WG List: <mailto:netconf@ietf.org>
-
- Author: Andy Bierman
- <mailto:andy@yumaworks.com>
-
- Author: Martin Bjorklund
- <mailto:mbj@tail-f.com>
-
- Author: Kent Watsen
- <mailto:kwatsen@juniper.net>";
-
- description
- "This module contains monitoring information for the
- RESTCONF protocol.
-
- Copyright (c) 2017 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 8040; see
- the RFC itself for full legal notices.";
-
- revision 2017-01-26 {
- description
- "Initial revision.";
- reference
- "RFC 8040: RESTCONF Protocol.";
- }
-
- container restconf-state {
- config false;
- description
- "Contains RESTCONF protocol monitoring information.";
-
- container capabilities {
- description
- "Contains a list of protocol capability URIs.";
-
- leaf-list capability {
- type inet:uri;
- description
- "A RESTCONF protocol capability URI.";
- }
- }
-
- container streams {
- description
- "Container representing the notification event streams
- supported by the server.";
- reference
- "RFC 5277, Section 3.4, <streams> element.";
-
- list stream {
- key name;
- description
- "Each entry describes an event stream supported by
- the server.";
-
- leaf name {
- type string;
- description
- "The stream name.";
- reference
- "RFC 5277, Section 3.4, <name> element.";
- }
-
- leaf description {
- type string;
- description
- "Description of stream content.";
- reference
- "RFC 5277, Section 3.4, <description> element.";
- }
-
- leaf replay-support {
- type boolean;
- default false;
- description
- "Indicates if replay buffer is supported for this stream.
- If 'true', then the server MUST support the 'start-time'
- and 'stop-time' query parameters for this stream.";
- reference
- "RFC 5277, Section 3.4, <replaySupport> element.";
- }
-
- leaf replay-log-creation-time {
- when "../replay-support" {
- description
- "Only present if notification replay is supported.";
- }
- type yang:date-and-time;
- description
- "Indicates the time the replay log for this stream
- was created.";
- reference
- "RFC 5277, Section 3.4, <replayLogCreationTime>
- element.";
- }
-
- list access {
- key encoding;
- min-elements 1;
- description
- "The server will create an entry in this list for each
- encoding format that is supported for this stream.
- The media type 'text/event-stream' is expected
- for all event streams. This list identifies the
- subtypes supported for this stream.";
-
- leaf encoding {
- type string;
- description
- "This is the secondary encoding format within the
- 'text/event-stream' encoding used by all streams.
- The type 'xml' is supported for XML encoding.
- The type 'json' is supported for JSON encoding.";
- }
-
- leaf location {
- type inet:uri;
- mandatory true;
- description
- "Contains a URL that represents the entry point
- for establishing notification delivery via
- server-sent events.";
- }
- }
- }
- }
- }
-}
+++ /dev/null
-module ietf-yang-library {
- namespace "urn:ietf:params:xml:ns:yang:ietf-yang-library";
- prefix "yanglib";
- import ietf-yang-types {
- prefix yang;
- }
- import ietf-inet-types {
- prefix inet;
- }
- organization
- "IETF NETCONF (Network Configuration) Working Group";
- contact
- "WG Web: <https://datatracker.ietf.org/wg/netconf/>
- WG List: <mailto:netconf@ietf.org>
- WG Chair: Mehmet Ersue
- <mailto:mehmet.ersue@nsn.com>
- WG Chair: Mahesh Jethanandani
- <mailto:mjethanandani@gmail.com>
- Editor: Andy Bierman
- <mailto:andy@yumaworks.com>
- Editor: Martin Bjorklund
- <mailto:mbj@tail-f.com>
- Editor: Kent Watsen
- <mailto:kwatsen@juniper.net>";
- description
- "This module contains monitoring information about the YANG
- modules and submodules that are used within a YANG-based
- server.
- Copyright (c) 2016 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 7895; see
- the RFC itself for full legal notices.";
- revision 2016-06-21 {
- description
- "Initial revision.";
- reference
- "RFC 7895: YANG Module Library.";
- }
- /*
- * Typedefs
- */
- typedef revision-identifier {
- type string {
- pattern '\d{4}-\d{2}-\d{2}';
- }
- description
- "Represents a specific date in YYYY-MM-DD format.";
- }
- /*
- * Groupings
- */
- grouping module-list {
- description
- "The module data structure is represented as a grouping
- so it can be reused in configuration or another monitoring
- data structure.";
- grouping common-leafs {
- description
- "Common parameters for YANG modules and submodules.";
- leaf name {
- type yang:yang-identifier;
- description
- "The YANG module or submodule name.";
- }
- leaf revision {
- type union {
- type revision-identifier;
- type string { length 0; }
- }
- description
- "The YANG module or submodule revision date.
- A zero-length string is used if no revision statement
- is present in the YANG module or submodule.";
- }
- }
- grouping schema-leaf {
- description
- "Common schema leaf parameter for modules and submodules.";
- leaf schema {
- type inet:uri;
- description
- "Contains a URL that represents the YANG schema
- resource for this module or submodule.
- This leaf will only be present if there is a URL
- available for retrieval of the schema for this entry.";
- }
- }
- list module {
- key "name revision";
- description
- "Each entry represents one revision of one module
- currently supported by the server.";
- uses common-leafs;
- uses schema-leaf;
- leaf namespace {
- type inet:uri;
- mandatory true;
- description
- "The XML namespace identifier for this module.";
- }
- leaf-list feature {
- type yang:yang-identifier;
- description
- "List of YANG feature names from this module that are
- supported by the server, regardless of whether they are
- defined in the module or any included submodule.";
- }
- list deviation {
- key "name revision";
- description
- "List of YANG deviation module names and revisions
- used by this server to modify the conformance of
- the module associated with this entry. Note that
- the same module can be used for deviations for
- multiple modules, so the same entry MAY appear
- within multiple 'module' entries.
- The deviation module MUST be present in the 'module'
- list, with the same name and revision values.
- The 'conformance-type' value will be 'implement' for
- the deviation module.";
- uses common-leafs;
- }
- leaf conformance-type {
- type enumeration {
- enum implement {
- description
- "Indicates that the server implements one or more
- protocol-accessible objects defined in the YANG module
- identified in this entry. This includes deviation
- statements defined in the module.
- For YANG version 1.1 modules, there is at most one
- module entry with conformance type 'implement' for a
- particular module name, since YANG 1.1 requires that,
- at most, one revision of a module is implemented.
- For YANG version 1 modules, there SHOULD NOT be more
- than one module entry for a particular module name.";
- }
- enum import {
- description
- "Indicates that the server imports reusable definitions
- from the specified revision of the module but does
- not implement any protocol-accessible objects from
- this revision.
- Multiple module entries for the same module name MAY
- exist. This can occur if multiple modules import the
- same module but specify different revision dates in
- the import statements.";
- }
- }
- mandatory true;
- description
- "Indicates the type of conformance the server is claiming
- for the YANG module identified by this entry.";
- }
- list submodule {
- key "name revision";
- description
- "Each entry represents one submodule within the
- parent module.";
- uses common-leafs;
- uses schema-leaf;
- }
- }
- }
- /*
- * Operational state data nodes
- */
- container modules-state {
- config false;
- description
- "Contains YANG module monitoring information.";
- leaf module-set-id {
- type string;
- mandatory true;
- description
- "Contains a server-specific identifier representing
- the current set of modules and submodules. The
- server MUST change the value of this leaf if the
- information represented by the 'module' list instances
- has changed.";
- }
- uses module-list;
- }
- /*
- * Notifications
- */
- notification yang-library-change {
- description
- "Generated when the set of modules and submodules supported
- by the server has changed.";
- leaf module-set-id {
- type leafref {
- path "/yanglib:modules-state/yanglib:module-set-id";
- }
- mandatory true;
- description
- "Contains the module-set-id value representing the
- set of modules and submodules supported at the server at
- the time the notification is generated.";
- }
- }
-}
+++ /dev/null
- 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)";
- }
-
- 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 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";
- }
-
- }
+++ /dev/null
-module invoke-rpc-module {
- namespace "invoke:rpc:module";
-
- prefix "inrpcmod";
-
- revision 2013-12-03 {
-
- }
-
- rpc rpc-test {
- input {
- container cont {
- leaf lf {
- type string;
- }
- }
- }
- output {
- container cont-out {
- leaf lf-out {
- type string;
- }
- }
- }
- }
-
- rpc rpc-noop {
- }
-
-}
+++ /dev/null
-{
- "invoke-rpc-module:input" : {
- "cont" : {
- "lf" : "lf-test"
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "invoke-rpc-module:output" : {
- "cont-out" : {
- "lf-out" : "lf-test"
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-<input xmlns="invoke:rpc:module">
- <cont>
- <lf>lf-test</lf>
- </cont>
-</input>
\ No newline at end of file
+++ /dev/null
-<output xmlns="invoke:rpc:module">
- <cont-out>
- <lf-out>lf-test</lf-out>
- </cont-out>
-</output>
\ No newline at end of file
+++ /dev/null
-{
- "array-with-null-yang:cont": {
- "lf":null
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "array-with-null-yang:cont": {
- "lflst1":[],
- "lflst2":[45]
- }
-}
+++ /dev/null
-{
- "cont": {
- "lf":
- }
-}
\ No newline at end of file
+++ /dev/null
-module identity-module {
- namespace "identity:module";
-
- prefix "idemod";
- revision 2013-12-02 {
- }
-
- identity iden {
- }
-}
+++ /dev/null
-module identityref-module {
- namespace "identityref:module";
-
- prefix "iderefmod";
-
- import identity-module {prefix idemo; revision-date 2013-12-02; }
-
- revision 2013-12-02 {
- }
-
- identity iden_local {
- }
-
- container cont {
- container cont1 {
- leaf lf11 {
- type identityref {
- base "idemo:iden";
- }
- }
- leaf lf12 {
- type identityref {
- base "iden_local";
- }
- }
- leaf lf13 {
- type identityref {
- base "iden_local";
- }
- }
- leaf lf14 {
- type identityref {
- base "iden_local";
- }
- }
- }
- }
-
-}
+++ /dev/null
-{
- "identityref:cont":{
- "cont1":{
- "lf11":"identity-module:iden",
- "lf12":"identityref-module:iden_local",
- "identityref-module:lf13":"identityref-module:iden_local",
- "identityref-module:lf14":"identity-module:iden"
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "array-with-null-yang:cont":{
- "lf1":"module<Name:value lf1",
- "lf2":"module>Name:value lf2"
- }
-}
+++ /dev/null
-module augment-leafref-module {
- namespace "augment:leafref:module";
-
- prefix "auglfrfmo";
- revision 2014-12-16;
-
- typedef leafreftype {
- type leafref {
- path "/auglfrfmo:cont/auglfrfmo:lf3";
- }
- }
-
- container cont {
- leaf lf3 {
- type string;
- }
- }
-}
+++ /dev/null
-{
- "leafref-module:cont":{
- "lf1":121,
- "lf2":121,
- "lf4":"pcc://39.39.39.39"
- }
-}
\ No newline at end of file
+++ /dev/null
-module leafref-module {
- namespace "leafref:module";
-
- prefix "lfrfmo";
-
- import augment-leafref-module {prefix augleafref; revision-date 2014-12-16;}
- revision 2013-11-18 {
- }
-
- container cont {
- leaf lf1 {
- type int32;
- }
- leaf lf2 {
- type leafref {
- path "/cont/lf1";
- }
- }
- leaf lf4 {
- type augleafref:leafreftype;
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-{
- "multiple-items-yang:lst":[
- {
- "lst1": [
- {
- "lf11":"lf11_1"
- },
- {
- "lflst11":[
- 45
- ]
- },
- {
- "cont11":{
- }
- },
- {
- "lst11":[
- {
- }
- ]
- }
- ]
- }
- ]
-}
+++ /dev/null
-{
- "simple-list-yang1:lst": {
- "lflst1":[45,55,66]
- }
-}
+++ /dev/null
-module simple-container-yang {
- namespace "simple:container:yang";
-
- prefix "smpdtp";
- revision 2013-11-12 {
- }
-
- container cont {
- container cont1 {
- }
- list lst1 {
- }
- leaf-list lflst1 {
- type string;
- }
- leaf lf1 {
- type string;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "simple-container-yang:cont":{
- "cont1":{
- },
- "lst1": [
- {
- }
- ],
- "lflst1":[
- "lflst1_1",
- "lflst1_2"
- ],
- "lf1":"lf1"
- }
-}
+++ /dev/null
-module simple-list-yang1 {
- namespace "simple:list:yang1";
-
- prefix "smplstyg";
- revision 2013-11-12 {
- }
-
- list lst {
- container cont1 {
- }
- list lst1 {
- }
- leaf-list lflst1 {
- type string;
- }
- leaf lf1 {
- type string;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-module simple-list-yang2 {
- namespace "simple:list:yang2";
-
- prefix "smplstyg";
- revision 2013-11-12 {
- }
-
- list lst {
- container cont1 {
- }
- list lst1 {
- }
- leaf-list lflst1 {
- type string;
- }
- leaf lf1 {
- type string;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-module multiple-items-yang {
- namespace "multiple:items:yang";
-
- prefix "mltitmsyg";
- revision 2013-11-12 {
- }
-
- list lst {
- list lst1 {
- leaf lf11{
- type string;
- }
- leaf-list lflst11{
- type string;
- }
- container cont11{
-
- }
- list lst11{
-
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-module array-with-null-yang {
- namespace "array:with:null:yang";
-
- prefix "arwnlyn";
- revision 2013-11-12 {
- }
-
- container cont{
- leaf lf{
- type empty;
- }
- leaf lf1{
- type string;
- }
- leaf lf2{
- type string;
- }
- leaf-list lflst1{
- type empty;
- }
-
- leaf-list lflst2{
- type string;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "simple-list-yang1:lst":[
- {
- "cont1":{
- },
- "lst1": [
- {
- }
- ],
- "lflst1":[
- "lflst1_1",
- "lflst1_2"
- ],
- "lf1":"lf1"
- }
- ]
-}
+++ /dev/null
-fffff
\ No newline at end of file
+++ /dev/null
-{
- "wrong":[
- {
- },
- {
- }
- ]
-}
+++ /dev/null
-{
-
- "simple-list-yang1:lst": {
- },
- "lst1":[
- {
- }
- ]
-}
+++ /dev/null
-{
- "lf":"hello"
-}
\ No newline at end of file
+++ /dev/null
-module augmented-jukebox {
-
- namespace "http://example.com/ns/augmented-jukebox";
- prefix "augmented-jbox";
-
- revision "2016-05-05" {
- description "Initial version.";
- }
-
- import example-jukebox {prefix jbox; revision-date "2015-04-04";}
-
- augment "/jbox:jukebox" {
- container augmented-library {
- }
- }
- }
\ No newline at end of file
+++ /dev/null
-module example-jukebox {
-
- namespace "http://example.com/ns/example-jukebox";
- prefix "jbox";
-
- organization "Example, Inc.";
- contact "support at example.com";
- description "Example Jukebox Data Model Module";
- revision "2015-04-04" {
- description "Initial version.";
- reference "example.com document 1-4673";
- }
-
- identity genre {
- description "Base for all genre types";
- }
-
- // abbreviated list of genre classifications
- identity alternative {
- base genre;
- description "Alternative music";
- }
- identity blues {
- base genre;
- description "Blues music";
- }
- identity country {
- base genre;
- description "Country music";
- }
- identity jazz {
- base genre;
- description "Jazz music";
- }
- identity pop {
- base genre;
- description "Pop music";
- }
- identity rock {
- base genre;
- description "Rock music";
- }
-
- container jukebox {
- presence
- "An empty container indicates that the jukebox
- service is available";
-
- description
- "Represents a jukebox resource, with a library, playlists,
- and a play operation.";
-
- container library {
-
- description "Represents the jukebox library resource.";
-
- list artist {
- key name;
-
- description
- "Represents one artist resource within the
- jukebox library resource.";
-
- leaf name {
- type string {
- length "1 .. max";
- }
- description "The name of the artist.";
- }
-
- list album {
- key name;
-
- description
- "Represents one album resource within one
- artist resource, within the jukebox library.";
-
- leaf name {
- type string {
- length "1 .. max";
- }
- description "The name of the album.";
- }
-
- leaf genre {
- type identityref { base genre; }
- description
- "The genre identifying the type of music on
- the album.";
- }
-
- leaf year {
- type uint16 {
- range "1900 .. max";
- }
- description "The year the album was released";
- }
-
- container admin {
- description
- "Administrative information for the album.";
-
- leaf label {
- type string;
- description "The label that released the album.";
- }
- leaf catalogue-number {
- type string;
- description "The album's catalogue number.";
- }
- }
-
- list song {
- key name;
-
- description
- "Represents one song resource within one
- album resource, within the jukebox library.";
-
- leaf name {
- type string {
- length "1 .. max";
- }
- description "The name of the song";
- }
- leaf location {
- type string;
- mandatory true;
- description
- "The file location string of the
- media file for the song";
- }
- leaf format {
- type string;
- description
- "An identifier string for the media type
- for the file associated with the
- 'location' leaf for this entry.";
- }
- leaf length {
- type uint32;
- units "seconds";
- description
- "The duration of this song in seconds.";
- }
- } // end list 'song'
- } // end list 'album'
- } // end list 'artist'
-
- leaf artist-count {
- type uint32;
- units "songs";
- config false;
- description "Number of artists in the library";
- }
- leaf album-count {
- type uint32;
- units "albums";
- config false;
- description "Number of albums in the library";
- }
- leaf song-count {
- type uint32;
- units "songs";
- config false;
- description "Number of songs in the library";
- }
- } // end library
-
- list playlist {
- key name;
-
- description
- "Example configuration data resource";
-
- leaf name {
- type string;
- description
- "The name of the playlist.";
- }
- leaf description {
- type string;
- description
- "A comment describing the playlist.";
- }
-
- list song {
- key index;
- ordered-by user;
-
- description
- "Example nested configuration data resource";
-
- leaf index { // not really needed
- type uint32;
- description
- "An arbitrary integer index for this playlist song.";
- }
- leaf id {
- type leafref {
- path "/jbox:jukebox/jbox:library/jbox:artist/" +
- "jbox:album/jbox:song/jbox:name";
- }
- mandatory true;
- description
- "Song identifier. Must identify an instance of
- /jukebox/library/artist/album/song/name.";
- }
- }
- }
-
- container player {
- description
- "Represents the jukebox player resource.";
-
- leaf gap {
- type decimal64 {
- fraction-digits 1;
- range "0.0 .. 2.0";
- }
- units "tenths of seconds";
- description "Time gap between each song";
- }
- }
- }
-
- rpc play {
- description "Control function for the jukebox player";
- input {
- leaf playlist {
- type string;
- mandatory true;
- description "playlist name";
- }
-
- leaf song-number {
- type uint32;
- mandatory true;
- description "Song number in playlist to play";
- }
- }
- }
- }
\ No newline at end of file
+++ /dev/null
- 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)";
- }
-
- }
+++ /dev/null
-module ietf-restconf-monitoring {
- namespace "urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring";
- prefix "rcmon";
-
- import ietf-yang-types { prefix yang; }
- import ietf-inet-types { prefix inet; }
-
- organization
- "IETF NETCONF (Network Configuration) Working Group";
-
- contact
- "WG Web: <https://datatracker.ietf.org/wg/netconf/>
- WG List: <mailto:netconf@ietf.org>
-
- Author: Andy Bierman
- <mailto:andy@yumaworks.com>
-
- Author: Martin Bjorklund
- <mailto:mbj@tail-f.com>
-
- Author: Kent Watsen
- <mailto:kwatsen@juniper.net>";
-
- description
- "This module contains monitoring information for the
- RESTCONF protocol.
-
- Copyright (c) 2017 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 8040; see
- the RFC itself for full legal notices.";
-
- revision 2017-01-26 {
- description
- "Initial revision.";
- reference
- "RFC 8040: RESTCONF Protocol.";
- }
-
- container restconf-state {
- config false;
- description
- "Contains RESTCONF protocol monitoring information.";
-
- container capabilities {
- description
- "Contains a list of protocol capability URIs.";
-
- leaf-list capability {
- type inet:uri;
- description
- "A RESTCONF protocol capability URI.";
- }
- }
-
- container streams {
- description
- "Container representing the notification event streams
- supported by the server.";
- reference
- "RFC 5277, Section 3.4, <streams> element.";
-
- list stream {
- key name;
- description
- "Each entry describes an event stream supported by
- the server.";
-
- leaf name {
- type string;
- description
- "The stream name.";
- reference
- "RFC 5277, Section 3.4, <name> element.";
- }
-
- leaf description {
- type string;
- description
- "Description of stream content.";
- reference
- "RFC 5277, Section 3.4, <description> element.";
- }
-
- leaf replay-support {
- type boolean;
- default false;
- description
- "Indicates if replay buffer is supported for this stream.
- If 'true', then the server MUST support the 'start-time'
- and 'stop-time' query parameters for this stream.";
- reference
- "RFC 5277, Section 3.4, <replaySupport> element.";
- }
-
- leaf replay-log-creation-time {
- when "../replay-support" {
- description
- "Only present if notification replay is supported.";
- }
- type yang:date-and-time;
- description
- "Indicates the time the replay log for this stream
- was created.";
- reference
- "RFC 5277, Section 3.4, <replayLogCreationTime>
- element.";
- }
-
- list access {
- key encoding;
- min-elements 1;
- description
- "The server will create an entry in this list for each
- encoding format that is supported for this stream.
- The media type 'text/event-stream' is expected
- for all event streams. This list identifies the
- subtypes supported for this stream.";
-
- leaf encoding {
- type string;
- description
- "This is the secondary encoding format within the
- 'text/event-stream' encoding used by all streams.
- The type 'xml' is supported for XML encoding.
- The type 'json' is supported for JSON encoding.";
- }
-
- leaf location {
- type inet:uri;
- mandatory true;
- description
- "Contains a URL that represents the entry point
- for establishing notification delivery via
- server-sent events.";
- }
- }
- }
- }
- }
-}
+++ /dev/null
-module ietf-yang-library {
- namespace "urn:ietf:params:xml:ns:yang:ietf-yang-library";
- prefix "yanglib";
- import ietf-yang-types {
- prefix yang;
- }
- import ietf-inet-types {
- prefix inet;
- }
- organization
- "IETF NETCONF (Network Configuration) Working Group";
- contact
- "WG Web: <https://datatracker.ietf.org/wg/netconf/>
- WG List: <mailto:netconf@ietf.org>
- WG Chair: Mehmet Ersue
- <mailto:mehmet.ersue@nsn.com>
- WG Chair: Mahesh Jethanandani
- <mailto:mjethanandani@gmail.com>
- Editor: Andy Bierman
- <mailto:andy@yumaworks.com>
- Editor: Martin Bjorklund
- <mailto:mbj@tail-f.com>
- Editor: Kent Watsen
- <mailto:kwatsen@juniper.net>";
- description
- "This module contains monitoring information about the YANG
- modules and submodules that are used within a YANG-based
- server.
- Copyright (c) 2016 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 7895; see
- the RFC itself for full legal notices.";
- revision 2016-06-21 {
- description
- "Initial revision.";
- reference
- "RFC 7895: YANG Module Library.";
- }
- /*
- * Typedefs
- */
- typedef revision-identifier {
- type string {
- pattern '\d{4}-\d{2}-\d{2}';
- }
- description
- "Represents a specific date in YYYY-MM-DD format.";
- }
- /*
- * Groupings
- */
- grouping module-list {
- description
- "The module data structure is represented as a grouping
- so it can be reused in configuration or another monitoring
- data structure.";
- grouping common-leafs {
- description
- "Common parameters for YANG modules and submodules.";
- leaf name {
- type yang:yang-identifier;
- description
- "The YANG module or submodule name.";
- }
- leaf revision {
- type union {
- type revision-identifier;
- type string { length 0; }
- }
- description
- "The YANG module or submodule revision date.
- A zero-length string is used if no revision statement
- is present in the YANG module or submodule.";
- }
- }
- grouping schema-leaf {
- description
- "Common schema leaf parameter for modules and submodules.";
- leaf schema {
- type inet:uri;
- description
- "Contains a URL that represents the YANG schema
- resource for this module or submodule.
- This leaf will only be present if there is a URL
- available for retrieval of the schema for this entry.";
- }
- }
- list module {
- key "name revision";
- description
- "Each entry represents one revision of one module
- currently supported by the server.";
- uses common-leafs;
- uses schema-leaf;
- leaf namespace {
- type inet:uri;
- mandatory true;
- description
- "The XML namespace identifier for this module.";
- }
- leaf-list feature {
- type yang:yang-identifier;
- description
- "List of YANG feature names from this module that are
- supported by the server, regardless of whether they are
- defined in the module or any included submodule.";
- }
- list deviation {
- key "name revision";
- description
- "List of YANG deviation module names and revisions
- used by this server to modify the conformance of
- the module associated with this entry. Note that
- the same module can be used for deviations for
- multiple modules, so the same entry MAY appear
- within multiple 'module' entries.
- The deviation module MUST be present in the 'module'
- list, with the same name and revision values.
- The 'conformance-type' value will be 'implement' for
- the deviation module.";
- uses common-leafs;
- }
- leaf conformance-type {
- type enumeration {
- enum implement {
- description
- "Indicates that the server implements one or more
- protocol-accessible objects defined in the YANG module
- identified in this entry. This includes deviation
- statements defined in the module.
- For YANG version 1.1 modules, there is at most one
- module entry with conformance type 'implement' for a
- particular module name, since YANG 1.1 requires that,
- at most, one revision of a module is implemented.
- For YANG version 1 modules, there SHOULD NOT be more
- than one module entry for a particular module name.";
- }
- enum import {
- description
- "Indicates that the server imports reusable definitions
- from the specified revision of the module but does
- not implement any protocol-accessible objects from
- this revision.
- Multiple module entries for the same module name MAY
- exist. This can occur if multiple modules import the
- same module but specify different revision dates in
- the import statements.";
- }
- }
- mandatory true;
- description
- "Indicates the type of conformance the server is claiming
- for the YANG module identified by this entry.";
- }
- list submodule {
- key "name revision";
- description
- "Each entry represents one submodule within the
- parent module.";
- uses common-leafs;
- uses schema-leaf;
- }
- }
- }
- /*
- * Operational state data nodes
- */
- container modules-state {
- config false;
- description
- "Contains YANG module monitoring information.";
- leaf module-set-id {
- type string;
- mandatory true;
- description
- "Contains a server-specific identifier representing
- the current set of modules and submodules. The
- server MUST change the value of this leaf if the
- information represented by the 'module' list instances
- has changed.";
- }
- uses module-list;
- }
- /*
- * Notifications
- */
- notification yang-library-change {
- description
- "Generated when the set of modules and submodules supported
- by the server has changed.";
- leaf module-set-id {
- type leafref {
- path "/yanglib:modules-state/yanglib:module-set-id";
- }
- mandatory true;
- description
- "Contains the module-set-id value representing the
- set of modules and submodules supported at the server at
- the time the notification is generated.";
- }
- }
-}
+++ /dev/null
- 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)";
- }
-
- 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 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";
- }
-
- }
+++ /dev/null
-{
- "leafref-module:cont" : {
- "lf4" : "/referenced-module:cont/referenced-module:lf1",
- "lf2" : "/leafref-module:cont/leafref-module:lf1",
- "lf3" : "/leafref-module:cont/leafref-module:lf2",
- "lf5" : "/leafref-module:cont/leafref-module:lf3"
- }
-}
\ No newline at end of file
+++ /dev/null
-<cont xmlnsa="leafref:module">
- <lf4 xmlns:nsa="referenced:module">/nsa:cont/nsa:lf1</lf4>
- <lf2 xmlns:nsa="leafref:module">/nsa:cont/nsa:lf1</lf2>
- <lf3 xmlns:ns="leafref:module">/ns:cont/ns:lf2</lf3>
- <lf5 xmlns:nsa="leafref:module">/nsa:cont/nsa:lf3</lf5>
-</cont>
+++ /dev/null
-module leafref-module {
- namespace "leafref:module";
-
-
- prefix "lfrfmodule";
-
- import referenced-module { prefix refmod; revision-date 2014-04-17;}
-
-
- revision 2014-04-17 {
- }
-
-
- container cont {
- leaf lf1 {
- type instance-identifier;
- }
-
- leaf lf2 {
- type leafref {
- path "../lf1";
- }
- }
-
- leaf lf3 {
- type leafref {
- path "/refmod:cont/refmod:lf1";
- }
- }
-
- leaf lf4 {
- type leafref {
- path "/cont/lf1";
- }
- }
-
- leaf lf5 {
- type leafref {
- path "../lf1";
- }
- }
-
- list lst-with-lfref-key {
- key "lfref-key";
-
- leaf lfref-key {
- type leafref {
- path "/refmod:cont/refmod:id-ref";
- }
- }
- }
-
- }
-}
+++ /dev/null
-module referenced-module {
- namespace "referenced:module";
-
- prefix "refmodule";
- revision 2014-04-17 {
- }
-
- container cont {
- leaf lf1 {
- type instance-identifier;
- }
-
- leaf id-ref {
- type leafref {
- path "../../id";
- }
- }
- }
-
- leaf id {
- type string;
- }
-}
+++ /dev/null
-{
- "notification": {
- "data-changed-notification": {
- "data-change-event": [
- {
- "data": {
- "my-leaf11": {
- "content": "Jed",
- "xmlns": "instance:identifier:patch:module"
- }
- },
- "operation": "created",
- "path": "/instance-identifier-patch-module:patch-cont/instance-identifier-patch-module:my-list1[instance-identifier-patch-module:name='Althea']/instance-identifier-patch-module:my-leaf11"
- },
- {
- "data": {
- "name": {
- "content": "Althea",
- "xmlns": "instance:identifier:patch:module"
- }
- },
- "operation": "created",
- "path": "/instance-identifier-patch-module:patch-cont/instance-identifier-patch-module:my-list1[instance-identifier-patch-module:name='Althea']/instance-identifier-patch-module:name"
- },
- {
- "data": {
- "patch-cont": {
- "my-list1": {
- "my-leaf11": "Jed",
- "name": "Althea"
- },
- "xmlns": "instance:identifier:patch:module"
- }
- },
- "operation": "created",
- "path": "/instance-identifier-patch-module:patch-cont"
- },
- {
- "data": {
- "my-list1": {
- "my-leaf11": "Jed",
- "name": "Althea",
- "xmlns": "instance:identifier:patch:module"
- }
- },
- "operation": "created",
- "path": "/instance-identifier-patch-module:patch-cont/instance-identifier-patch-module:my-list1[instance-identifier-patch-module:name='Althea']"
- }
- ],
- "xmlns": "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote"
- },
- "eventTime": "2017-09-17T13:32:03.586+03:00",
- "xmlns": "urn:ietf:params:xml:ns:netconf:notification:1.0"
- }
-}
+++ /dev/null
-{
- "notification": {
- "data-changed-notification": {
- "data-change-event": [
- {
- "operation": "deleted",
- "path": "/instance-identifier-patch-module:patch-cont"
- },
- {
- "operation": "deleted",
- "path": "/instance-identifier-patch-module:patch-cont/instance-identifier-patch-module:my-list1[instance-identifier-patch-module:name='Althea']"
- },
- {
- "operation": "deleted",
- "path": "/instance-identifier-patch-module:patch-cont/instance-identifier-patch-module:my-list1[instance-identifier-patch-module:name='Althea']/instance-identifier-patch-module:name"
- },
- {
- "operation": "deleted",
- "path": "/instance-identifier-patch-module:patch-cont/instance-identifier-patch-module:my-list1[instance-identifier-patch-module:name='Althea']/instance-identifier-patch-module:my-leaf12"
- },
- {
- "operation": "deleted",
- "path": "/instance-identifier-patch-module:patch-cont/instance-identifier-patch-module:my-list1[instance-identifier-patch-module:name='Althea']/instance-identifier-patch-module:my-leaf11"
- }
- ],
- "xmlns": "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote"
- },
- "eventTime": "2017-09-17T14:18:53.404+03:00",
- "xmlns": "urn:ietf:params:xml:ns:netconf:notification:1.0"
- }
-}
+++ /dev/null
-{
- "notification": {
- "data-changed-notification": {
- "data-change-event": [
- {
- "data": {
- "my-leaf11": {
- "content": "Jed",
- "xmlns": "instance:identifier:patch:module"
- }
- },
- "operation": "created",
- "path": "/instance-identifier-patch-module:patch-cont/instance-identifier-patch-module:my-list1[instance-identifier-patch-module:name='Althea']/instance-identifier-patch-module:my-leaf11"
- },
- {
- "data": {
- "name": {
- "content": "Althea",
- "xmlns": "instance:identifier:patch:module"
- }
- },
- "operation": "created",
- "path": "/instance-identifier-patch-module:patch-cont/instance-identifier-patch-module:my-list1[instance-identifier-patch-module:name='Althea']/instance-identifier-patch-module:name"
- }
- ],
- "xmlns": "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote"
- },
- "eventTime": "2017-09-17T11:23:10.323+03:00",
- "xmlns": "urn:ietf:params:xml:ns:netconf:notification:1.0"
- }
-}
+++ /dev/null
-{
- "notification": {
- "data-changed-notification": {
- "data-change-event": [
- {
- "operation": "deleted",
- "path": "/instance-identifier-patch-module:patch-cont/instance-identifier-patch-module:my-list1[instance-identifier-patch-module:name='Althea']/instance-identifier-patch-module:my-leaf11"
- },
- {
- "operation": "deleted",
- "path": "/instance-identifier-patch-module:patch-cont/instance-identifier-patch-module:my-list1[instance-identifier-patch-module:name='Althea']/instance-identifier-patch-module:name"
- },
- {
- "operation": "deleted",
- "path": "/instance-identifier-patch-module:patch-cont/instance-identifier-patch-module:my-list1[instance-identifier-patch-module:name='Althea']/instance-identifier-patch-module:my-leaf12"
- }
- ],
- "xmlns": "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote"
- },
- "eventTime": "2017-09-18T15:30:16.099+03:00",
- "xmlns": "urn:ietf:params:xml:ns:netconf:notification:1.0"
- }
-}
+++ /dev/null
-{
- "notification": {
- "data-changed-notification": {
- "data-change-event": [
- {
- "data": {
- "my-leaf12": {
- "content": "Bertha",
- "xmlns": "instance:identifier:patch:module"
- }
- },
- "operation": "created",
- "path": "/instance-identifier-patch-module:patch-cont/instance-identifier-patch-module:my-list1[instance-identifier-patch-module:name='Althea']/instance-identifier-patch-module:my-leaf12"
- },
- {
- "data": {
- "name": {
- "content": "Althea",
- "xmlns": "instance:identifier:patch:module"
- }
- },
- "operation": "updated",
- "path": "/instance-identifier-patch-module:patch-cont/instance-identifier-patch-module:my-list1[instance-identifier-patch-module:name='Althea']/instance-identifier-patch-module:name"
- }
- ],
- "xmlns": "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote"
- },
- "eventTime": "2017-09-18T14:20:54.82+03:00",
- "xmlns": "urn:ietf:params:xml:ns:netconf:notification:1.0"
- }
-}
+++ /dev/null
-{
- "notification": {
- "data-changed-notification": {
- "data-change-event": [
- {
- "data": {
- "patch-cont": {
- "my-list1": {
- "my-leaf11": "Jed",
- "my-leaf12": "Bertha",
- "name": "Althea"
- },
- "xmlns": "instance:identifier:patch:module"
- }
- },
- "operation": "updated",
- "path": "/instance-identifier-patch-module:patch-cont"
- },
- {
- "data": {
- "my-list1": {
- "my-leaf11": "Jed",
- "my-leaf12": "Bertha",
- "name": "Althea",
- "xmlns": "instance:identifier:patch:module"
- }
- },
- "operation": "updated",
- "path": "/instance-identifier-patch-module:patch-cont/instance-identifier-patch-module:my-list1[instance-identifier-patch-module:name='Althea']"
- },
- {
- "data": {
- "my-leaf12": {
- "content": "Bertha",
- "xmlns": "instance:identifier:patch:module"
- }
- },
- "operation": "created",
- "path": "/instance-identifier-patch-module:patch-cont/instance-identifier-patch-module:my-list1[instance-identifier-patch-module:name='Althea']/instance-identifier-patch-module:my-leaf12"
- },
- {
- "data": {
- "name": {
- "content": "Althea",
- "xmlns": "instance:identifier:patch:module"
- }
- },
- "operation": "updated",
- "path": "/instance-identifier-patch-module:patch-cont/instance-identifier-patch-module:my-list1[instance-identifier-patch-module:name='Althea']/instance-identifier-patch-module:name"
- }
- ],
- "xmlns": "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote"
- },
- "eventTime": "2017-09-18T15:52:25.213+03:00",
- "xmlns": "urn:ietf:params:xml:ns:netconf:notification:1.0"
- }
-}
+++ /dev/null
-{
- "notification":{
- "xmlns":"urn:ietf:params:xml:ns:netconf:notification:1.0",
- "data-changed-notification":{
- "xmlns":"urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote",
- "data-change-event":{
- "path":"/instance-identifier-patch-module:patch-cont",
- "operation":"created"
- }
- },
- "eventTime":"2020-05-31T18:45:05.132101+05:30"
- }
-}
+++ /dev/null
-{
- "notification":{
- "xmlns":"urn:ietf:params:xml:ns:netconf:notification:1.0",
- "data-changed-notification":{
- "xmlns":"urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote",
- "data-change-event":{
- "path":"/instance-identifier-patch-module:patch-cont",
- "operation":"deleted"
- }
- },
- "eventTime":"2020-05-31T18:45:05.132101+05:30"
- }
-}
+++ /dev/null
-{
- "notification":{
- "xmlns":"urn:ietf:params:xml:ns:netconf:notification:1.0",
- "data-changed-notification":{
- "xmlns":"urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote",
- "data-change-event":{
- "path":"/instance-identifier-patch-module:patch-cont",
- "operation":"updated"
- }
- },
- "eventTime":"2020-05-31T18:45:05.132101+05:30"
- }
-}
+++ /dev/null
-module iana-if-type {
- namespace "urn:ietf:params:xml:ns:yang:iana-if-type";
- prefix ianaift;
-
- organization "IANA";
- contact
- " Internet Assigned Numbers Authority
-
- Postal: ICANN
- 4676 Admiralty Way, Suite 330
- Marina del Rey, CA 90292
-
- Tel: +1 310 823 9358
- E-Mail: iana&iana.org";
- description
- "This YANG module defines the iana-if-type typedef, which
- contains YANG definitions for IANA-registered interface types.
-
- This YANG module is maintained by IANA, and reflects the
- 'ifType definitions' registry.
-
- The latest revision of this YANG module can be obtained from
- the IANA web site.
-
- Copyright (c) 2011 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 XXXX; see
- the RFC itself for full legal notices.";
- // RFC Ed.: replace XXXX with actual RFC number and remove this
- // note.
-
- // RFC Ed.: update the date below with the date of RFC publication
- // and remove this note.
- revision 2013-07-04 {
- description
- "Initial revision.";
- reference
- "RFC XXXX: IANA Interface Type YANG Module";
- }
-
- typedef iana-if-type {
- type enumeration {
- enum "other" {
- value 1;
- description
- "None of the following";
- }
- enum "regular1822" {
- value 2;
- }
- enum "hdh1822" {
- value 3;
- }
- enum "ddnX25" {
- value 4;
- }
- enum "rfc877x25" {
- value 5;
- reference
- "RFC 1382 - SNMP MIB Extension for the X.25 Packet Layer";
- }
- enum "ethernetCsmacd" {
- value 6;
- description
- "For all ethernet-like interfaces, regardless of speed,
- as per RFC3635.";
- reference
- "RFC 3635 - Definitions of Managed Objects for the
- Ethernet-like Interface Types.";
- }
- enum "iso88023Csmacd" {
- value 7;
- status deprecated;
- description
- "Deprecated via RFC3635.
- Use ethernetCsmacd(6) instead.";
- reference
- "RFC 3635 - Definitions of Managed Objects for the
- Ethernet-like Interface Types.";
- }
- enum "iso88024TokenBus" {
- value 8;
- }
- enum "iso88025TokenRing" {
- value 9;
- }
- enum "iso88026Man" {
- value 10;
- }
- enum "starLan" {
- value 11;
- status deprecated;
- description
- "Deprecated via RFC3635.
- Use ethernetCsmacd(6) instead.";
- reference
- "RFC 3635 - Definitions of Managed Objects for the
- Ethernet-like Interface Types.";
- }
- enum "proteon10Mbit" {
- value 12;
- }
- enum "proteon80Mbit" {
- value 13;
- }
- enum "hyperchannel" {
- value 14;
- }
- enum "fddi" {
- value 15;
- reference
- "RFC 1512 - FDDI Management Information Base";
- }
- enum "lapb" {
- value 16;
- reference
- "RFC 1381 - SNMP MIB Extension for X.25 LAPB";
- }
- enum "sdlc" {
- value 17;
- }
- enum "ds1" {
- value 18;
- description
- "DS1-MIB";
- reference
- "RFC 4805 - Definitions of Managed Objects for the
- DS1, J1, E1, DS2, and E2 Interface Types";
- }
- enum "e1" {
- value 19;
- status obsolete;
- description
- "Obsolete see DS1-MIB";
- reference
- "RFC 4805 - Definitions of Managed Objects for the
- DS1, J1, E1, DS2, and E2 Interface Types";
- }
- enum "basicISDN" {
- value 20;
- description
- "see also RFC2127";
- }
- enum "primaryISDN" {
- value 21;
- }
- enum "propPointToPointSerial" {
- value 22;
- description
- "proprietary serial";
- }
- enum "ppp" {
- value 23;
- }
- enum "softwareLoopback" {
- value 24;
- }
- enum "eon" {
- value 25;
- description
- "CLNP over IP";
- }
- enum "ethernet3Mbit" {
- value 26;
- }
- enum "nsip" {
- value 27;
- description
- "XNS over IP";
- }
- enum "slip" {
- value 28;
- description
- "generic SLIP";
- }
- enum "ultra" {
- value 29;
- description
- "ULTRA technologies";
- }
- enum "ds3" {
- value 30;
- description
- "DS3-MIB";
- reference
- "RFC 3896 - Definitions of Managed Objects for the
- DS3/E3 Interface Type";
- }
- enum "sip" {
- value 31;
- description
- "SMDS, coffee";
- reference
- "RFC 1694 - Definitions of Managed Objects for SMDS
- Interfaces using SMIv2";
- }
- enum "frameRelay" {
- value 32;
- description
- "DTE only.";
- reference
- "RFC 2115 - Management Information Base for Frame Relay
- DTEs Using SMIv2";
- }
- enum "rs232" {
- value 33;
- reference
- "RFC 1659 - Definitions of Managed Objects for RS-232-like
- Hardware Devices using SMIv2";
- }
- enum "para" {
- value 34;
- description
- "parallel-port";
- reference
- "RFC 1660 - Definitions of Managed Objects for
- Parallel-printer-like Hardware Devices using
- SMIv2";
- }
- enum "arcnet" {
- value 35;
- description
- "arcnet";
- }
- enum "arcnetPlus" {
- value 36;
- description
- "arcnet plus";
- }
- enum "atm" {
- value 37;
- description
- "ATM cells";
- }
- enum "miox25" {
- value 38;
- reference
- "RFC 1461 - SNMP MIB extension for Multiprotocol
- Interconnect over X.25";
- }
- enum "sonet" {
- value 39;
- description
- "SONET or SDH";
- }
- enum "x25ple" {
- value 40;
- reference
- "RFC 2127 - ISDN Management Information Base using SMIv2";
- }
- enum "iso88022llc" {
- value 41;
- }
- enum "localTalk" {
- value 42;
- }
- enum "smdsDxi" {
- value 43;
- }
- enum "frameRelayService" {
- value 44;
- description
- "FRNETSERV-MIB";
- reference
- "RFC 2954 - Definitions of Managed Objects for Frame
- Relay Service";
- }
- enum "v35" {
- value 45;
- }
- enum "hssi" {
- value 46;
- }
- enum "hippi" {
- value 47;
- }
- enum "modem" {
- value 48;
- description
- "Generic modem";
- }
- enum "aal5" {
- value 49;
- description
- "AAL5 over ATM";
- }
- enum "sonetPath" {
- value 50;
- }
- enum "sonetVT" {
- value 51;
- }
- enum "smdsIcip" {
- value 52;
- description
- "SMDS InterCarrier Interface";
- }
- enum "propVirtual" {
- value 53;
- description
- "proprietary virtual/internal";
- reference
- "RFC 2863 - The Interfaces Group MIB";
- }
- enum "propMultiplexor" {
- value 54;
- description
- "proprietary multiplexing";
- reference
- "RFC 2863 - The Interfaces Group MIB";
- }
- enum "ieee80212" {
- value 55;
- description
- "100BaseVG";
- }
- enum "fibreChannel" {
- value 56;
- description
- "Fibre Channel";
- }
- enum "hippiInterface" {
- value 57;
- description
- "HIPPI interfaces";
- }
- enum "frameRelayInterconnect" {
- value 58;
- status obsolete;
- description
- "Obsolete use either
- frameRelay(32) or frameRelayService(44).";
- }
- enum "aflane8023" {
- value 59;
- description
- "ATM Emulated LAN for 802.3";
- }
- enum "aflane8025" {
- value 60;
- description
- "ATM Emulated LAN for 802.5";
- }
- enum "cctEmul" {
- value 61;
- description
- "ATM Emulated circuit";
- }
- enum "fastEther" {
- value 62;
- status deprecated;
- description
- "Obsoleted via RFC3635.
- ethernetCsmacd(6) should be used instead";
- reference
- "RFC 3635 - Definitions of Managed Objects for the
- Ethernet-like Interface Types.";
- }
- enum "isdn" {
- value 63;
- description
- "ISDN and X.25";
- reference
- "RFC 1356 - Multiprotocol Interconnect on X.25 and ISDN
- in the Packet Mode";
- }
- enum "v11" {
- value 64;
- description
- "CCITT V.11/X.21";
- }
- enum "v36" {
- value 65;
- description
- "CCITT V.36";
- }
- enum "g703at64k" {
- value 66;
- description
- "CCITT G703 at 64Kbps";
- }
- enum "g703at2mb" {
- value 67;
- status obsolete;
- description
- "Obsolete see DS1-MIB";
- }
- enum "qllc" {
- value 68;
- description
- "SNA QLLC";
- }
- enum "fastEtherFX" {
- value 69;
- status deprecated;
- description
- "Obsoleted via RFC3635
- ethernetCsmacd(6) should be used instead";
- reference
- "RFC 3635 - Definitions of Managed Objects for the
- Ethernet-like Interface Types.";
- }
- enum "channel" {
- value 70;
- description
- "channel";
- }
- enum "ieee80211" {
- value 71;
- description
- "radio spread spectrum";
- }
- enum "ibm370parChan" {
- value 72;
- description
- "IBM System 360/370 OEMI Channel";
- }
- enum "escon" {
- value 73;
- description
- "IBM Enterprise Systems Connection";
- }
- enum "dlsw" {
- value 74;
- description
- "Data Link Switching";
- }
- enum "isdns" {
- value 75;
- description
- "ISDN S/T interface";
- }
- enum "isdnu" {
- value 76;
- description
- "ISDN U interface";
- }
- enum "lapd" {
- value 77;
- description
- "Link Access Protocol D";
- }
- enum "ipSwitch" {
- value 78;
- description
- "IP Switching Objects";
- }
- enum "rsrb" {
- value 79;
- description
- "Remote Source Route Bridging";
- }
- enum "atmLogical" {
- value 80;
- description
- "ATM Logical Port";
- reference
- "RFC 3606 - Definitions of Supplemental Managed Objects
- for ATM Interface";
- }
- enum "ds0" {
- value 81;
- description
- "Digital Signal Level 0";
- reference
- "RFC 2494 - Definitions of Managed Objects for the DS0
- and DS0 Bundle Interface Type";
- }
- enum "ds0Bundle" {
- value 82;
- description
- "group of ds0s on the same ds1";
- reference
- "RFC 2494 - Definitions of Managed Objects for the DS0
- and DS0 Bundle Interface Type";
- }
- enum "bsc" {
- value 83;
- description
- "Bisynchronous Protocol";
- }
- enum "async" {
- value 84;
- description
- "Asynchronous Protocol";
- }
- enum "cnr" {
- value 85;
- description
- "Combat Net Radio";
- }
- enum "iso88025Dtr" {
- value 86;
- description
- "ISO 802.5r DTR";
- }
- enum "eplrs" {
- value 87;
- description
- "Ext Pos Loc Report Sys";
- }
- enum "arap" {
- value 88;
- description
- "Appletalk Remote Access Protocol";
- }
- enum "propCnls" {
- value 89;
- description
- "Proprietary Connectionless Protocol";
- }
- enum "hostPad" {
- value 90;
- description
- "CCITT-ITU X.29 PAD Protocol";
- }
- enum "termPad" {
- value 91;
- description
- "CCITT-ITU X.3 PAD Facility";
- }
- enum "frameRelayMPI" {
- value 92;
- description
- "Multiproto Interconnect over FR";
- }
- enum "x213" {
- value 93;
- description
- "CCITT-ITU X213";
- }
- enum "adsl" {
- value 94;
- description
- "Asymmetric Digital Subscriber Loop";
- }
- enum "radsl" {
- value 95;
- description
- "Rate-Adapt. Digital Subscriber Loop";
- }
- enum "sdsl" {
- value 96;
- description
- "Symmetric Digital Subscriber Loop";
- }
- enum "vdsl" {
- value 97;
- description
- "Very H-Speed Digital Subscrib. Loop";
- }
- enum "iso88025CRFPInt" {
- value 98;
- description
- "ISO 802.5 CRFP";
- }
- enum "myrinet" {
- value 99;
- description
- "Myricom Myrinet";
- }
- enum "voiceEM" {
- value 100;
- description
- "voice recEive and transMit";
- }
- enum "voiceFXO" {
- value 101;
- description
- "voice Foreign Exchange Office";
- }
- enum "voiceFXS" {
- value 102;
- description
- "voice Foreign Exchange Station";
- }
- enum "voiceEncap" {
- value 103;
- description
- "voice encapsulation";
- }
- enum "voiceOverIp" {
- value 104;
- description
- "voice over IP encapsulation";
- }
- enum "atmDxi" {
- value 105;
- description
- "ATM DXI";
- }
- enum "atmFuni" {
- value 106;
- description
- "ATM FUNI";
- }
- enum "atmIma" {
- value 107;
- description
- "ATM IMA";
- }
- enum "pppMultilinkBundle" {
- value 108;
- description
- "PPP Multilink Bundle";
- }
- enum "ipOverCdlc" {
- value 109;
- description
- "IBM ipOverCdlc";
- }
- enum "ipOverClaw" {
- value 110;
- description
- "IBM Common Link Access to Workstn";
- }
- enum "stackToStack" {
- value 111;
- description
- "IBM stackToStack";
- }
- enum "virtualIpAddress" {
- value 112;
- description
- "IBM VIPA";
- }
- enum "mpc" {
- value 113;
- description
- "IBM multi-protocol channel support";
- }
- enum "ipOverAtm" {
- value 114;
- description
- "IBM ipOverAtm";
- reference
- "RFC 2320 - Definitions of Managed Objects for Classical IP
- and ARP Over ATM Using SMIv2 (IPOA-MIB)";
- }
- enum "iso88025Fiber" {
- value 115;
- description
- "ISO 802.5j Fiber Token Ring";
- }
- enum "tdlc" {
- value 116;
- description
- "IBM twinaxial data link control";
- }
- enum "gigabitEthernet" {
- value 117;
- status deprecated;
- description
- "Obsoleted via RFC3635
- ethernetCsmacd(6) should be used instead";
- reference
- "RFC 3635 - Definitions of Managed Objects for the
- Ethernet-like Interface Types.";
- }
- enum "hdlc" {
- value 118;
- description
- "HDLC";
- }
- enum "lapf" {
- value 119;
- description
- "LAP F";
- }
- enum "v37" {
- value 120;
- description
- "V.37";
- }
- enum "x25mlp" {
- value 121;
- description
- "Multi-Link Protocol";
- }
- enum "x25huntGroup" {
- value 122;
- description
- "X25 Hunt Group";
- }
- enum "transpHdlc" {
- value 123;
- description
- "Transp HDLC";
- }
- enum "interleave" {
- value 124;
- description
- "Interleave channel";
- }
- enum "fast" {
- value 125;
- description
- "Fast channel";
- }
- enum "ip" {
- value 126;
- description
- "IP (for APPN HPR in IP networks)";
- }
- enum "docsCableMaclayer" {
- value 127;
- description
- "CATV Mac Layer";
- }
- enum "docsCableDownstream" {
- value 128;
- description
- "CATV Downstream interface";
- }
- enum "docsCableUpstream" {
- value 129;
- description
- "CATV Upstream interface";
- }
- enum "a12MppSwitch" {
- value 130;
- description
- "Avalon Parallel Processor";
- }
- enum "tunnel" {
- value 131;
- description
- "Encapsulation interface";
- }
- enum "coffee" {
- value 132;
- description
- "coffee pot";
- reference
- "RFC 2325 - Coffee MIB";
- }
- enum "ces" {
- value 133;
- description
- "Circuit Emulation Service";
- }
- enum "atmSubInterface" {
- value 134;
- description
- "ATM Sub Interface";
- }
- enum "l2vlan" {
- value 135;
- description
- "Layer 2 Virtual LAN using 802.1Q";
- }
- enum "l3ipvlan" {
- value 136;
- description
- "Layer 3 Virtual LAN using IP";
- }
- enum "l3ipxvlan" {
- value 137;
- description
- "Layer 3 Virtual LAN using IPX";
- }
- enum "digitalPowerline" {
- value 138;
- description
- "IP over Power Lines";
- }
- enum "mediaMailOverIp" {
- value 139;
- description
- "Multimedia Mail over IP";
- }
- enum "dtm" {
- value 140;
- description
- "Dynamic syncronous Transfer Mode";
- }
- enum "dcn" {
- value 141;
- description
- "Data Communications Network";
- }
- enum "ipForward" {
- value 142;
- description
- "IP Forwarding Interface";
- }
- enum "msdsl" {
- value 143;
- description
- "Multi-rate Symmetric DSL";
- }
- enum "ieee1394" {
- value 144;
- description
- "IEEE1394 High Performance Serial Bus";
- }
- enum "if-gsn" {
- value 145;
- description
- "HIPPI-6400";
- }
- enum "dvbRccMacLayer" {
- value 146;
- description
- "DVB-RCC MAC Layer";
- }
- enum "dvbRccDownstream" {
- value 147;
- description
- "DVB-RCC Downstream Channel";
- }
- enum "dvbRccUpstream" {
- value 148;
- description
- "DVB-RCC Upstream Channel";
- }
- enum "atmVirtual" {
- value 149;
- description
- "ATM Virtual Interface";
- }
- enum "mplsTunnel" {
- value 150;
- description
- "MPLS Tunnel Virtual Interface";
- }
- enum "srp" {
- value 151;
- description
- "Spatial Reuse Protocol";
- }
- enum "voiceOverAtm" {
- value 152;
- description
- "Voice Over ATM";
- }
- enum "voiceOverFrameRelay" {
- value 153;
- description
- "Voice Over Frame Relay";
- }
- enum "idsl" {
- value 154;
- description
- "Digital Subscriber Loop over ISDN";
- }
- enum "compositeLink" {
- value 155;
- description
- "Avici Composite Link Interface";
- }
- enum "ss7SigLink" {
- value 156;
- description
- "SS7 Signaling Link";
- }
- enum "propWirelessP2P" {
- value 157;
- description
- "Prop. P2P wireless interface";
- }
- enum "frForward" {
- value 158;
- description
- "Frame Forward Interface";
- }
- enum "rfc1483" {
- value 159;
- description
- "Multiprotocol over ATM AAL5";
- reference
- "RFC 1483 - Multiprotocol Encapsulation over ATM
- Adaptation Layer 5";
- }
- enum "usb" {
- value 160;
- description
- "USB Interface";
- }
- enum "ieee8023adLag" {
- value 161;
- description
- "IEEE 802.3ad Link Aggregate";
- }
- enum "bgppolicyaccounting" {
- value 162;
- description
- "BGP Policy Accounting";
- }
- enum "frf16MfrBundle" {
- value 163;
- description
- "FRF .16 Multilink Frame Relay";
- }
- enum "h323Gatekeeper" {
- value 164;
- description
- "H323 Gatekeeper";
- }
- enum "h323Proxy" {
- value 165;
- description
- "H323 Voice and Video Proxy";
- }
- enum "mpls" {
- value 166;
- description
- "MPLS";
- }
- enum "mfSigLink" {
- value 167;
- description
- "Multi-frequency signaling link";
- }
- enum "hdsl2" {
- value 168;
- description
- "High Bit-Rate DSL - 2nd generation";
- }
- enum "shdsl" {
- value 169;
- description
- "Multirate HDSL2";
- }
- enum "ds1FDL" {
- value 170;
- description
- "Facility Data Link 4Kbps on a DS1";
- }
- enum "pos" {
- value 171;
- description
- "Packet over SONET/SDH Interface";
- }
- enum "dvbAsiIn" {
- value 172;
- description
- "DVB-ASI Input";
- }
- enum "dvbAsiOut" {
- value 173;
- description
- "DVB-ASI Output";
- }
- enum "plc" {
- value 174;
- description
- "Power Line Communtications";
- }
- enum "nfas" {
- value 175;
- description
- "Non Facility Associated Signaling";
- }
- enum "tr008" {
- value 176;
- description
- "TR008";
- }
- enum "gr303RDT" {
- value 177;
- description
- "Remote Digital Terminal";
- }
- enum "gr303IDT" {
- value 178;
- description
- "Integrated Digital Terminal";
- }
- enum "isup" {
- value 179;
- description
- "ISUP";
- }
- enum "propDocsWirelessMaclayer" {
- value 180;
- description
- "Cisco proprietary Maclayer";
- }
- enum "propDocsWirelessDownstream" {
- value 181;
- description
- "Cisco proprietary Downstream";
- }
- enum "propDocsWirelessUpstream" {
- value 182;
- description
- "Cisco proprietary Upstream";
- }
- enum "hiperlan2" {
- value 183;
- description
- "HIPERLAN Type 2 Radio Interface";
- }
- enum "propBWAp2Mp" {
- value 184;
- description
- "PropBroadbandWirelessAccesspt2multipt use of this value
- for IEEE 802.16 WMAN interfaces as per IEEE Std 802.16f
- is deprecated and ieee80216WMAN(237) should be used
- instead.";
- }
- enum "sonetOverheadChannel" {
- value 185;
- description
- "SONET Overhead Channel";
- }
- enum "digitalWrapperOverheadChannel" {
- value 186;
- description
- "Digital Wrapper";
- }
- enum "aal2" {
- value 187;
- description
- "ATM adaptation layer 2";
- }
- enum "radioMAC" {
- value 188;
- description
- "MAC layer over radio links";
- }
- enum "atmRadio" {
- value 189;
- description
- "ATM over radio links";
- }
- enum "imt" {
- value 190;
- description
- "Inter Machine Trunks";
- }
- enum "mvl" {
- value 191;
- description
- "Multiple Virtual Lines DSL";
- }
- enum "reachDSL" {
- value 192;
- description
- "Long Reach DSL";
- }
- enum "frDlciEndPt" {
- value 193;
- description
- "Frame Relay DLCI End Point";
- }
- enum "atmVciEndPt" {
- value 194;
- description
- "ATM VCI End Point";
- }
- enum "opticalChannel" {
- value 195;
- description
- "Optical Channel";
- }
- enum "opticalTransport" {
- value 196;
- description
- "Optical Transport";
- }
- enum "propAtm" {
- value 197;
- description
- "Proprietary ATM";
- }
- enum "voiceOverCable" {
- value 198;
- description
- "Voice Over Cable Interface";
- }
- enum "infiniband" {
- value 199;
- description
- "Infiniband";
- }
- enum "teLink" {
- value 200;
- description
- "TE Link";
- }
- enum "q2931" {
- value 201;
- description
- "Q.2931";
- }
- enum "virtualTg" {
- value 202;
- description
- "Virtual Trunk Group";
- }
- enum "sipTg" {
- value 203;
- description
- "SIP Trunk Group";
- }
- enum "sipSig" {
- value 204;
- description
- "SIP Signaling";
- }
- enum "docsCableUpstreamChannel" {
- value 205;
- description
- "CATV Upstream Channel";
- }
- enum "econet" {
- value 206;
- description
- "Acorn Econet";
- }
- enum "pon155" {
- value 207;
- description
- "FSAN 155Mb Symetrical PON interface";
- }
- enum "pon622" {
- value 208;
- description
- "FSAN622Mb Symetrical PON interface";
- }
- enum "bridge" {
- value 209;
- description
- "Transparent bridge interface";
- }
- enum "linegroup" {
- value 210;
- description
- "Interface common to multiple lines";
- }
- enum "voiceEMFGD" {
- value 211;
- description
- "voice E&M Feature Group D";
- }
- enum "voiceFGDEANA" {
- value 212;
- description
- "voice FGD Exchange Access North American";
- }
- enum "voiceDID" {
- value 213;
- description
- "voice Direct Inward Dialing";
- }
- enum "mpegTransport" {
- value 214;
- description
- "MPEG transport interface";
- }
- enum "sixToFour" {
- value 215;
- status deprecated;
- description
- "6to4 interface (DEPRECATED)";
- reference
- "RFC 4087 - IP Tunnel MIB";
- }
- enum "gtp" {
- value 216;
- description
- "GTP (GPRS Tunneling Protocol)";
- }
- enum "pdnEtherLoop1" {
- value 217;
- description
- "Paradyne EtherLoop 1";
- }
- enum "pdnEtherLoop2" {
- value 218;
- description
- "Paradyne EtherLoop 2";
- }
- enum "opticalChannelGroup" {
- value 219;
- description
- "Optical Channel Group";
- }
- enum "homepna" {
- value 220;
- description
- "HomePNA ITU-T G.989";
- }
- enum "gfp" {
- value 221;
- description
- "Generic Framing Procedure (GFP)";
- }
- enum "ciscoISLvlan" {
- value 222;
- description
- "Layer 2 Virtual LAN using Cisco ISL";
- }
- enum "actelisMetaLOOP" {
- value 223;
- description
- "Acteleis proprietary MetaLOOP High Speed Link";
- }
- enum "fcipLink" {
- value 224;
- description
- "FCIP Link";
- }
- enum "rpr" {
- value 225;
- description
- "Resilient Packet Ring Interface Type";
- }
- enum "qam" {
- value 226;
- description
- "RF Qam Interface";
- }
- enum "lmp" {
- value 227;
- description
- "Link Management Protocol";
- reference
- "RFC 4327 - Link Management Protocol (LMP) Management
- Information Base (MIB)";
- }
- enum "cblVectaStar" {
- value 228;
- description
- "Cambridge Broadband Networks Limited VectaStar";
- }
- enum "docsCableMCmtsDownstream" {
- value 229;
- description
- "CATV Modular CMTS Downstream Interface";
- }
- enum "adsl2" {
- value 230;
- status deprecated;
- description
- "Asymmetric Digital Subscriber Loop Version 2
- (DEPRECATED/OBSOLETED - please use adsl2plus(238)
- instead)";
- reference
- "RFC 4706 - Definitions of Managed Objects for Asymmetric
- Digital Subscriber Line 2 (ADSL2)";
- }
- enum "macSecControlledIF" {
- value 231;
- description
- "MACSecControlled";
- }
- enum "macSecUncontrolledIF" {
- value 232;
- description
- "MACSecUncontrolled";
- }
- enum "aviciOpticalEther" {
- value 233;
- description
- "Avici Optical Ethernet Aggregate";
- }
- enum "atmbond" {
- value 234;
- description
- "atmbond";
- }
- enum "voiceFGDOS" {
- value 235;
- description
- "voice FGD Operator Services";
- }
- enum "mocaVersion1" {
- value 236;
- description
- "MultiMedia over Coax Alliance (MoCA) Interface
- as documented in information provided privately to IANA";
- }
- enum "ieee80216WMAN" {
- value 237;
- description
- "IEEE 802.16 WMAN interface";
- }
- enum "adsl2plus" {
- value 238;
- description
- "Asymmetric Digital Subscriber Loop Version 2,
- Version 2 Plus and all variants";
- }
- enum "dvbRcsMacLayer" {
- value 239;
- description
- "DVB-RCS MAC Layer";
- reference
- "RFC 5728 - The SatLabs Group DVB-RCS MIB";
- }
- enum "dvbTdm" {
- value 240;
- description
- "DVB Satellite TDM";
- reference
- "RFC 5728 - The SatLabs Group DVB-RCS MIB";
- }
- enum "dvbRcsTdma" {
- value 241;
- description
- "DVB-RCS TDMA";
- reference
- "RFC 5728 - The SatLabs Group DVB-RCS MIB";
- }
- enum "x86Laps" {
- value 242;
- description
- "LAPS based on ITU-T X.86/Y.1323";
- }
- enum "wwanPP" {
- value 243;
- description
- "3GPP WWAN";
- }
- enum "wwanPP2" {
- value 244;
- description
- "3GPP2 WWAN";
- }
- enum "voiceEBS" {
- value 245;
- description
- "voice P-phone EBS physical interface";
- }
- enum "ifPwType" {
- value 246;
- description
- "Pseudowire interface type";
- reference
- "RFC 5601 - Pseudowire (PW) Management Information Base";
- }
- enum "ilan" {
- value 247;
- description
- "Internal LAN on a bridge per IEEE 802.1ap";
- }
- enum "pip" {
- value 248;
- description
- "Provider Instance Port on a bridge per IEEE 802.1ah PBB";
- }
- enum "aluELP" {
- value 249;
- description
- "Alcatel-Lucent Ethernet Link Protection";
- }
- enum "gpon" {
- value 250;
- description
- "Gigabit-capable passive optical networks (G-PON) as per
- ITU-T G.948";
- }
- enum "vdsl2" {
- value 251;
- description
- "Very high speed digital subscriber line Version 2
- (as per ITU-T Recommendation G.993.2)";
- reference
- "RFC 5650 - Definitions of Managed Objects for Very High
- Speed Digital Subscriber Line 2 (VDSL2)";
- }
- enum "capwapDot11Profile" {
- value 252;
- description
- "WLAN Profile Interface";
- reference
- "RFC 5834 - Control and Provisioning of Wireless Access
- Points (CAPWAP) Protocol Binding MIB for
- IEEE 802.11";
- }
- enum "capwapDot11Bss" {
- value 253;
- description
- "WLAN BSS Interface";
- reference
- "RFC 5834 - Control and Provisioning of Wireless Access
- Points (CAPWAP) Protocol Binding MIB for
- IEEE 802.11";
- }
- enum "capwapWtpVirtualRadio" {
- value 254;
- description
- "WTP Virtual Radio Interface";
- reference
- "RFC 5833 - Control and Provisioning of Wireless Access
- Points (CAPWAP) Protocol Base MIB";
- }
- enum "bits" {
- value 255;
- description
- "bitsport";
- }
- enum "docsCableUpstreamRfPort" {
- value 256;
- description
- "DOCSIS CATV Upstream RF Port";
- }
- enum "cableDownstreamRfPort" {
- value 257;
- description
- "CATV downstream RF port";
- }
- enum "vmwareVirtualNic" {
- value 258;
- description
- "VMware Virtual Network Interface";
- }
- enum "ieee802154" {
- value 259;
- description
- "IEEE 802.15.4 WPAN interface";
- reference
- "IEEE 802.15.4-2006";
- }
- enum "otnOdu" {
- value 260;
- description
- "OTN Optical Data Unit";
- }
- enum "otnOtu" {
- value 261;
- description
- "OTN Optical channel Transport Unit";
- }
- enum "ifVfiType" {
- value 262;
- description
- "VPLS Forwarding Instance Interface Type";
- }
- enum "g9981" {
- value 263;
- description
- "G.998.1 bonded interface";
- }
- enum "g9982" {
- value 264;
- description
- "G.998.2 bonded interface";
- }
- enum "g9983" {
- value 265;
- description
- "G.998.3 bonded interface";
- }
- enum "aluEpon" {
- value 266;
- description
- "Ethernet Passive Optical Networks (E-PON)";
- }
- enum "aluEponOnu" {
- value 267;
- description
- "EPON Optical Network Unit";
- }
- enum "aluEponPhysicalUni" {
- value 268;
- description
- "EPON physical User to Network interface";
- }
- enum "aluEponLogicalLink" {
- value 269;
- description
- "The emulation of a point-to-point link over the EPON
- layer";
- }
- enum "aluGponOnu" {
- value 270;
- description
- "GPON Optical Network Unit";
- reference
- "ITU-T G.984.2";
- }
- enum "aluGponPhysicalUni" {
- value 271;
- description
- "GPON physical User to Network interface";
- reference
- "ITU-T G.984.2";
- }
- enum "vmwareNicTeam" {
- value 272;
- description
- "VMware NIC Team";
- }
- // value 273 reserved by IANA
- }
- description
- "This data type is used as the syntax of the 'type'
- leaf in the 'interface' list in the YANG module
- ietf-interface.
-
- The definition of this typedef with the
- addition of newly assigned values is published
- periodically by the IANA, in either the Assigned
- Numbers RFC, or some derivative of it specific to
- Internet Network Management number assignments. (The
- latest arrangements can be obtained by contacting the
- IANA.)
-
- Requests for new values should be made to IANA via
- email (iana&iana.org).";
- reference
- "IANA ifType definitions registry.
- <http://www.iana.org/assignments/smi-numbers>";
- }
-}
\ No newline at end of file
+++ /dev/null
- 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)";
- }
-
- }
+++ /dev/null
-module ietf-interfaces {
-
- namespace "urn:ietf:params:xml:ns:yang:ietf-interfaces";
- prefix if;
-
- import ietf-yang-types {
- prefix yang;
- }
- import iana-if-type {
- prefix ianaift;
- }
-
- 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: Martin Bjorklund
- <mailto:mbj@tail-f.com>";
-
- description
- "This module contains a collection of YANG definitions for
- managing network interfaces.
-
- 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 XXXX; see
- the RFC itself for full legal notices.";
-
- // RFC Ed.: replace XXXX with actual RFC number and remove this
- // note.
-
- // RFC Ed.: update the date below with the date of RFC publication
- // and remove this note.
- revision 2013-07-04 {
- description
- "Initial revision.";
- reference
- "RFC XXXX: A YANG Data Model for Interface Management";
- }
-
- /* Typedefs */
-
- typedef interface-ref {
- type leafref {
- path "/if:interfaces/if:interface/if:name";
- }
- description
- "This type is used by data models that need to reference
- configured interfaces.";
- }
-
- typedef interface-state-ref {
- type leafref {
- path "/if:interfaces-state/if:interface/if:name";
- }
- description
- "This type is used by data models that need to reference
- the operationally present interfaces.";
- }
-
- /* Features */
-
- feature arbitrary-names {
- description
- "This feature indicates that the device allows user-controlled
- interfaces to be named arbitrarily.";
- }
-
- feature pre-provisioning {
- description
- "This feature indicates that the device supports
- pre-provisioning of interface configuration, i.e., it is
- possible to configure an interface whose physical interface
- hardware is not present on the device.";
- }
-
- feature if-mib {
- description
- "This feature indicates that the device implements IF-MIB.";
- reference
- "RFC 2863: The Interfaces Group MIB";
- }
-
- /* Data nodes */
-
- container interfaces {
- description
- "Interface configuration parameters.";
-
- list interface {
- key "name";
-
- description
- "The list of configured interfaces on the device.
-
- The operational state of an interface is available in the
- /interfaces-state/interface list. If the configuration of a
- system-controlled interface cannot be used by the system
- (e.g., the interface hardware present does not match the
- interface type), then the configuration is not applied to
- the system-controlled interface shown in the
- /interfaces-state/interface list. If the the configuration
- of a user-controlled interface cannot be used by the system,
- the configured interface is not instantiated in the
- /interfaces-state/interface list.";
-
- leaf name {
- type string;
- description
- "The name of the interface.
-
- A device MAY restrict the allowed values for this leaf,
- possibly depending on the type of the interface.
-
- For system-controlled interfaces, this leaf is the
- device-specific name of the interface. The 'config false'
- list /interfaces-state/interface contains the currently
- existing interfaces on the device.
-
- If a client tries to create configuration for a
- system-controlled interface that is not present in the
- /interfaces-state/interface list, the server MAY reject
- the request, if the implementation does not support
- pre-provisioning of interfaces, or if the name refers to
- an interface that can never exist in the system. A
- NETCONF server MUST reply with an rpc-error with the
- error-tag 'invalid-value' in this case.
-
- If the device supports pre-provisioning of interface
- configuration, the feature 'pre-provisioning' is
- advertised.
-
- If the device allows arbitrarily named user-controlled
- interfaces, the feature 'arbitrary-names' is advertised.
-
- When a configured user-controlled interface is created by
- the system, it is instantiated with the same name in the
- /interface-state/interface list. Since the name in that
- list MAY be mapped to ifName by an implementation, such an
- implementation MUST restrict the allowed values for this
- leaf so that it matches the restrictions of ifName.
-
- If a NETCONF server that implements this restriction is
- sent a value that doesn't match the restriction, it MUST
- reply with an rpc-error with the error-tag
- 'invalid-value'.";
- }
-
- leaf description {
- type string;
- description
- "A textual description of the interface.
-
- This leaf MAY be mapped to ifAlias by an implementation.
- Such an implementation MUST restrict the allowed values
- for this leaf so that it matches the restrictions of
- ifAlias.
-
- If a NETCONF server that implements this restriction is
- sent a value that doesn't match the restriction, it MUST
- reply with an rpc-error with the error-tag
- 'invalid-value'.
-
- Since ifAlias is defined to be stored in non-volatile
- storage, the MIB implementation MUST map ifAlias to the
- value of 'description' in the persistently stored
- datastore.
-
- Specifically, if the device supports ':startup', when
- ifAlias is read the device MUST return the value of
- 'description' in the 'startup' datastore, and when it is
- written, it MUST be written to the 'running' and 'startup'
- datastores. Note that it is up to the implementation if
- it modifies this single leaf in 'startup', or if it
- performs an implicit copy-config from 'running' to
- 'startup'.
-
- If the device does not support ':startup', ifAlias MUST
- be mapped to the 'description' leaf in the 'running'
- datastore.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifAlias";
- }
-
- leaf type {
- type ianaift:iana-if-type;
- mandatory true;
- description
- "The type of the interface.
-
- When an interface entry is created, a server MAY
- initialize the type leaf with a valid value, e.g., if it
- is possible to derive the type from the name of the
- interface.
-
- If a client tries to set the type of an interface to a
- value that can never be used by the system, e.g., if the
- type is not supported or if the type does not match the
- name of the interface, the server MUST reject the request.
- A NETCONF server MUST reply with an rpc-error with the
- error-tag 'invalid-value' in this case.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifType";
- }
-
- leaf enabled {
- type boolean;
- default "true";
- description
- "This leaf contains the configured, desired state of the
- interface.
-
- Systems that implement the IF-MIB use the value of this
- leaf in the 'running' datastore to set
- IF-MIB.ifAdminStatus to 'up' or 'down' after an ifEntry
- has been initialized, as described in RFC 2863.
-
- Changes in this leaf in the 'running' datastore are
- reflected in ifAdminStatus, but if ifAdminStatus is
- changed over SNMP, this leaf is not affected.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifAdminStatus";
- }
-
- leaf link-up-down-trap-enable {
- if-feature if-mib;
- type enumeration {
- enum enabled {
- value 1;
- }
- enum disabled {
- value 2;
- }
- }
- description
- "Controls whether linkUp/linkDown SNMP notifications
- should be generated for this interface.
-
- If this node is not configured, the value 'enabled' is
- operationally used by the server for interfaces which do
- not operate on top of any other interface (i.e., there are
- no 'lower-layer-if' entries), and 'disabled' otherwise.";
- reference
- "RFC 2863: The Interfaces Group MIB -
- ifLinkUpDownTrapEnable";
- }
- }
- }
-
- container interfaces-state {
- config false;
- description
- "Data nodes for the operational state of interfaces.";
-
- list interface {
- key "name";
-
- description
- "The list of interfaces on the device.
-
- System-controlled interfaces created by the system are
- always present in this list, whether they are configured or
- not.";
-
- leaf name {
- type string;
- description
- "The name of the interface.
-
- This leaf MAY be mapped to ifName by an implementation.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifName";
- }
-
- leaf type {
- type ianaift:iana-if-type;
- mandatory true;
- description
- "The type of the interface.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifType";
- }
-
- leaf admin-status {
- if-feature if-mib;
- type enumeration {
- enum up {
- value 1;
- description
- "Ready to pass packets.";
- }
- enum down {
- value 2;
- description
- "Not ready to pass packets and not in some test mode.";
- }
- enum testing {
- value 3;
- description
- "In some test mode.";
- }
- }
- mandatory true;
- description
- "The desired state of the interface.
-
- This leaf has the same read semantics as ifAdminStatus.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifAdminStatus";
- }
-
- leaf oper-status {
- type enumeration {
- enum up {
- value 1;
- description
- "Ready to pass packets.";
- }
- enum down {
- value 2;
- description
- "The interface does not pass any packets.";
- }
- enum testing {
- value 3;
- description
- "In some test mode. No operational packets can
- be passed.";
- }
- enum unknown {
- value 4;
- description
- "Status cannot be determined for some reason.";
- }
- enum dormant {
- value 5;
- description
- "Waiting for some external event.";
- }
- enum not-present {
- value 6;
- description
- "Some component (typically hardware) is missing.";
- }
- enum lower-layer-down {
- value 7;
- description
- "Down due to state of lower-layer interface(s).";
- }
- }
- mandatory true;
- description
- "The current operational state of the interface.
-
- This leaf has the same semantics as ifOperStatus.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifOperStatus";
- }
-
- leaf last-change {
- type yang:date-and-time;
- description
- "The time the interface entered its current operational
- state. If the current state was entered prior to the
- last re-initialization of the local network management
- subsystem, then this node is not present.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifLastChange";
- }
-
- leaf if-index {
- if-feature if-mib;
- type int32 {
- range "1..2147483647";
- }
- mandatory true;
- description
- "The ifIndex value for the ifEntry represented by this
- interface.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifIndex";
- }
-
- leaf phys-address {
- type yang:phys-address;
- description
- "The interface's address at its protocol sub-layer. For
- example, for an 802.x interface, this object normally
- contains a MAC address. The interface's media-specific
- modules must define the bit and byte ordering and the
- format of the value of this object. For interfaces that do
- not have such an address (e.g., a serial line), this node
- is not present.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifPhysAddress";
- }
-
- leaf-list higher-layer-if {
- type interface-state-ref;
- description
- "A list of references to interfaces layered on top of this
- interface.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifStackTable";
- }
-
- leaf-list lower-layer-if {
- type interface-state-ref;
- description
- "A list of references to interfaces layered underneath this
- interface.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifStackTable";
- }
-
- leaf speed {
- type yang:gauge64;
- units "bits / second";
- description
- "An estimate of the interface's current bandwidth in bits
- per second. For interfaces that do not vary in
- bandwidth or for those where no accurate estimation can
- be made, this node should contain the nominal bandwidth.
- For interfaces that have no concept of bandwidth, this
- node is not present.";
- reference
- "RFC 2863: The Interfaces Group MIB -
- ifSpeed, ifHighSpeed";
- }
-
- container statistics {
- description
- "A collection of interface-related statistics objects.";
-
- leaf discontinuity-time {
- type yang:date-and-time;
- mandatory true;
- description
- "The time on the most recent occasion at which any one or
- more of this interface's counters suffered a
- discontinuity. If no such discontinuities have occurred
- since the last re-initialization of the local management
- subsystem, then this node contains the time the local
- management subsystem re-initialized itself.";
- }
-
- leaf in-octets {
- type yang:counter64;
- description
- "The total number of octets received on the interface,
- including framing characters.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifHCInOctets";
- }
- leaf in-unicast-pkts {
- type yang:counter64;
- description
- "The number of packets, delivered by this sub-layer to a
- higher (sub-)layer, which were not addressed to a
- multicast or broadcast address at this sub-layer.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifHCInUcastPkts";
- }
- leaf in-broadcast-pkts {
- type yang:counter64;
- description
- "The number of packets, delivered by this sub-layer to a
- higher (sub-)layer, which were addressed to a broadcast
- address at this sub-layer.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB -
- ifHCInBroadcastPkts";
- }
- leaf in-multicast-pkts {
- type yang:counter64;
- description
- "The number of packets, delivered by this sub-layer to a
- higher (sub-)layer, which were addressed to a multicast
- address at this sub-layer. For a MAC layer protocol,
- this includes both Group and Functional addresses.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB -
- ifHCInMulticastPkts";
- }
- leaf in-discards {
- type yang:counter32;
- description
- "The number of inbound packets which were chosen to be
- discarded even though no errors had been detected to
- prevent their being deliverable to a higher-layer
- protocol. One possible reason for discarding such a
- packet could be to free up buffer space.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifInDiscards";
- }
- leaf in-errors {
- type yang:counter32;
- description
- "For packet-oriented interfaces, the number of inbound
- packets that contained errors preventing them from being
- deliverable to a higher-layer protocol. For character-
- oriented or fixed-length interfaces, the number of
- inbound transmission units that contained errors
- preventing them from being deliverable to a higher-layer
- protocol.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifInErrors";
- }
- leaf in-unknown-protos {
- type yang:counter32;
- description
- "For packet-oriented interfaces, the number of packets
- received via the interface which were discarded because
- of an unknown or unsupported protocol. For
- character-oriented or fixed-length interfaces that
- support protocol multiplexing the number of transmission
- units received via the interface which were discarded
- because of an unknown or unsupported protocol. For any
- interface that does not support protocol multiplexing,
- this counter is not present.
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifInUnknownProtos";
- }
-
- leaf out-octets {
- type yang:counter64;
- description
- "The total number of octets transmitted out of the
- interface, including framing characters.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifHCOutOctets";
- }
- leaf out-unicast-pkts {
- type yang:counter64;
- description
- "The total number of packets that higher-level protocols
- requested be transmitted, and which were not addressed
- to a multicast or broadcast address at this sub-layer,
- including those that were discarded or not sent.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifHCOutUcastPkts";
- }
- leaf out-broadcast-pkts {
- type yang:counter64;
- description
- "The total number of packets that higher-level protocols
- requested be transmitted, and which were addressed to a
- broadcast address at this sub-layer, including those
- that were discarded or not sent.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB -
- ifHCOutBroadcastPkts";
- }
- leaf out-multicast-pkts {
- type yang:counter64;
- description
- "The total number of packets that higher-level protocols
- requested be transmitted, and which were addressed to a
- multicast address at this sub-layer, including those
- that were discarded or not sent. For a MAC layer
- protocol, this includes both Group and Functional
- addresses.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB -
- ifHCOutMulticastPkts";
- }
- leaf out-discards {
- type yang:counter32;
- description
- "The number of outbound packets which were chosen to be
- discarded even though no errors had been detected to
- prevent their being transmitted. One possible reason
- for discarding such a packet could be to free up buffer
- space.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifOutDiscards";
- }
- leaf out-errors {
- type yang:counter32;
- description
- "For packet-oriented interfaces, the number of outbound
- packets that could not be transmitted because of errors.
- For character-oriented or fixed-length interfaces, the
- number of outbound transmission units that could not be
- transmitted because of errors.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifOutErrors";
- }
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-module ietf-restconf-monitoring {
- namespace "urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring";
- prefix "rcmon";
-
- import ietf-yang-types { prefix yang; }
- import ietf-inet-types { prefix inet; }
-
- organization
- "IETF NETCONF (Network Configuration) Working Group";
-
- contact
- "WG Web: <https://datatracker.ietf.org/wg/netconf/>
- WG List: <mailto:netconf@ietf.org>
-
- Author: Andy Bierman
- <mailto:andy@yumaworks.com>
-
- Author: Martin Bjorklund
- <mailto:mbj@tail-f.com>
-
- Author: Kent Watsen
- <mailto:kwatsen@juniper.net>";
-
- description
- "This module contains monitoring information for the
- RESTCONF protocol.
-
- Copyright (c) 2017 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 8040; see
- the RFC itself for full legal notices.";
-
- revision 2017-01-26 {
- description
- "Initial revision.";
- reference
- "RFC 8040: RESTCONF Protocol.";
- }
-
- container restconf-state {
- config false;
- description
- "Contains RESTCONF protocol monitoring information.";
-
- container capabilities {
- description
- "Contains a list of protocol capability URIs.";
-
- leaf-list capability {
- type inet:uri;
- description
- "A RESTCONF protocol capability URI.";
- }
- }
-
- container streams {
- description
- "Container representing the notification event streams
- supported by the server.";
- reference
- "RFC 5277, Section 3.4, <streams> element.";
-
- list stream {
- key name;
- description
- "Each entry describes an event stream supported by
- the server.";
-
- leaf name {
- type string;
- description
- "The stream name.";
- reference
- "RFC 5277, Section 3.4, <name> element.";
- }
-
- leaf description {
- type string;
- description
- "Description of stream content.";
- reference
- "RFC 5277, Section 3.4, <description> element.";
- }
-
- leaf replay-support {
- type boolean;
- default false;
- description
- "Indicates if replay buffer is supported for this stream.
- If 'true', then the server MUST support the 'start-time'
- and 'stop-time' query parameters for this stream.";
- reference
- "RFC 5277, Section 3.4, <replaySupport> element.";
- }
-
- leaf replay-log-creation-time {
- when "../replay-support" {
- description
- "Only present if notification replay is supported.";
- }
- type yang:date-and-time;
- description
- "Indicates the time the replay log for this stream
- was created.";
- reference
- "RFC 5277, Section 3.4, <replayLogCreationTime>
- element.";
- }
-
- list access {
- key encoding;
- min-elements 1;
- description
- "The server will create an entry in this list for each
- encoding format that is supported for this stream.
- The media type 'text/event-stream' is expected
- for all event streams. This list identifies the
- subtypes supported for this stream.";
-
- leaf encoding {
- type string;
- description
- "This is the secondary encoding format within the
- 'text/event-stream' encoding used by all streams.
- The type 'xml' is supported for XML encoding.
- The type 'json' is supported for JSON encoding.";
- }
-
- leaf location {
- type inet:uri;
- mandatory true;
- description
- "Contains a URL that represents the entry point
- for establishing notification delivery via
- server-sent events.";
- }
- }
- }
- }
- }
-}
+++ /dev/null
-module ietf-restconf {
- namespace "urn:ietf:params:xml:ns:yang:ietf-restconf";
- prefix "restconf";
-
- import ietf-yang-types { prefix yang; }
- import ietf-inet-types { prefix inet; }
-
- organization
- "IETF NETCONF (Network Configuration) Working Group";
-
- contact
- "Editor: Andy Bierman
- <mailto:andy@yumaworks.com>
-
- Editor: Martin Bjorklund
- <mailto:mbj@tail-f.com>
-
- Editor: Kent Watsen
- <mailto:kwatsen@juniper.net>
-
- Editor: Rex Fernando
- <mailto:rex@cisco.com>";
-
- description
- "This module contains conceptual YANG specifications
- for the YANG Patch and error content that is used in
- RESTCONF protocol messages. A conceptual container
- representing the RESTCONF API nodes (media type
- application/yang.api).
-
- Note that the YANG definitions within this module do not
- represent configuration data of any kind.
- The YANG grouping statements provide a normative syntax
- for XML and JSON message encoding purposes.
- 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 XXXX; see
- the RFC itself for full legal notices.";
-
- // RFC Ed.: replace XXXX with actual RFC number and remove this
- // note.
-
- // RFC Ed.: remove this note
- // Note: extracted from draft-bierman-netconf-restconf-02.txt
-
- // RFC Ed.: update the date below with the date of RFC publication
- // and remove this note.
- revision 2013-10-19 {
- description
- "Initial revision.";
- reference
- "RFC XXXX: RESTCONF Protocol.";
- }
-
- typedef data-resource-identifier {
- type string {
- length "1 .. max";
- }
- description
- "Contains a Data Resource Identifier formatted string
- to identify a specific data node. The data node that
- uses this data type SHOULD define the document root
- for data resource identifiers. The default document
- root is the target datastore conceptual root node.
- Data resource identifiers are defined relative to
- this document root.";
- reference
- "RFC XXXX: [sec. 5.3.1.1 ABNF For Data Resource Identifiers]";
- }
-
- // this typedef is TBD; not currently used
- typedef datastore-identifier {
- type union {
- type enumeration {
- enum candidate {
- description
- "Identifies the NETCONF shared candidate datastore.";
- reference
- "RFC 6241, section 8.3";
- }
- enum running {
- description
- "Identifies the NETCONF running datastore.";
- reference
- "RFC 6241, section 5.1";
- }
- enum startup {
- description
- "Identifies the NETCONF startup datastore.";
- reference
- "RFC 6241, section 8.7";
- }
- }
- type string;
- }
- description
- "Contains a string to identify a specific datastore.
- The enumerated datastore identifier values are
- reserved for standard datastore names.";
- }
-
- typedef revision-identifier {
- type string {
- pattern '\d{4}-\d{2}-\d{2}';
- }
- description
- "Represents a specific date in YYYY-MM-DD format.
- TBD: make pattern more precise to exclude leading zeros.";
- }
-
- grouping yang-patch {
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of a
- YANG Patch edit request message.";
-
- container yang-patch {
- description
- "Represents a conceptual sequence of datastore edits,
- called a patch. Each patch is given a client-assigned
- patch identifier. Each edit MUST be applied
- in ascending order, and all edits MUST be applied.
- If any errors occur, then the target datastore MUST NOT
- be changed by the patch operation.
-
- A patch MUST be validated by the server to be a
- well-formed message before any of the patch edits
- are validated or attempted.
-
- YANG datastore validation (defined in RFC 6020, section
- 8.3.3) is performed after all edits have been
- individually validated.
-
- It is possible for a datastore constraint violation to occur
- due to any node in the datastore, including nodes not
- included in the edit list. Any validation errors MUST
- be reported in the reply message.";
-
- reference
- "RFC 6020, section 8.3.";
-
- leaf patch-id {
- type string;
- description
- "An arbitrary string provided by the client to identify
- the entire patch. This value SHOULD be present in any
- audit logging records generated by the server for the
- patch. Error messages returned by the server pertaining
- to this patch will be identified by this patch-id value.";
- }
-
- leaf comment {
- type string {
- length "0 .. 1024";
- }
- description
- "An arbitrary string provided by the client to describe
- the entire patch. This value SHOULD be present in any
- audit logging records generated by the server for the
- patch.";
- }
-
- list edit {
- key edit-id;
- ordered-by user;
-
- description
- "Represents one edit within the YANG Patch
- request message.";
- leaf edit-id {
- type string;
- description
- "Arbitrary string index for the edit.
- Error messages returned by the server pertaining
- to a specific edit will be identified by this
- value.";
- }
-
- leaf operation {
- type enumeration {
- enum create {
- description
- "The target data node is created using the
- supplied value, only if it does not already
- exist.";
- }
- enum delete {
- description
- "Delete the target node, only if the data resource
- currently exists, otherwise return an error.";
- }
- enum insert {
- description
- "Insert the supplied value into a user-ordered
- list or leaf-list entry. The target node must
- represent a new data resource.";
- }
- enum merge {
- description
- "The supplied value is merged with the target data
- node.";
- }
- enum move {
- description
- "Move the target node. Reorder a user-ordered
- list or leaf-list. The target node must represent
- an existing data resource.";
- }
- enum replace {
- description
- "The supplied value is used to replace the target
- data node.";
- }
- enum remove {
- description
- "Delete the target node if it currently exists.";
- }
- }
- mandatory true;
- description
- "The datastore operation requested for the associated
- edit entry";
- }
-
- leaf target {
- type data-resource-identifier;
- mandatory true;
- description
- "Identifies the target data resource for the edit
- operation.";
- }
-
- leaf point {
- when "(../operation = 'insert' or " +
- "../operation = 'move') and " +
- "(../where = 'before' or ../where = 'after')" {
- description
- "Point leaf only applies for insert or move
- operations, before or after an existing entry.";
- }
- type data-resource-identifier;
- description
- "The absolute URL path for the data node that is being
- used as the insertion point or move point for the
- target of this edit entry.";
- }
-
- leaf where {
- when "../operation = 'insert' or ../operation = 'move'" {
- description
- "Where leaf only applies for insert or move
- operations.";
- }
- type enumeration {
- enum before {
- description
- "Insert or move a data node before the data resource
- identified by the 'point' parameter.";
- }
- enum after {
- description
- "Insert or move a data node after the data resource
- identified by the 'point' parameter.";
- }
- enum first {
- description
- "Insert or move a data node so it becomes ordered
- as the first entry.";
- }
- enum last {
- description
- "Insert or move a data node so it becomes ordered
- as the last entry.";
- }
-
- }
- default last;
- description
- "Identifies where a data resource will be inserted or
- moved. YANG only allows these operations for
- list and leaf-list data nodes that are ordered-by
- user.";
- }
-
- anyxml value {
- when "(../operation = 'create' or " +
- "../operation = 'merge' " +
- "or ../operation = 'replace' or " +
- "../operation = 'insert')" {
- description
- "Value node only used for create, merge,
- replace, and insert operations";
- }
- description
- "Value used for this edit operation.";
- }
- }
- }
-
- } // grouping yang-patch
-
-
- grouping yang-patch-status {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of
- YANG Patch status response message.";
-
- container yang-patch-status {
- description
- "A container representing the response message
- sent by the server after a YANG Patch edit
- request message has been processed.";
-
- leaf patch-id {
- type string;
- description
- "The patch-id value used in the request";
- }
-
- choice global-status {
- description
- "Report global errors or complete success.
- If there is no case selected then errors
- are reported in the edit-status container.";
-
- case global-errors {
- uses errors;
- description
- "This container will be present if global
- errors unrelated to a specific edit occurred.";
- }
- leaf ok {
- type empty;
- description
- "This leaf will be present if the request succeeded
- and there are no errors reported in the edit-status
- container.";
- }
- }
-
- container edit-status {
- description
- "This container will be present if there are
- edit-specific status responses to report.";
-
- list edit {
- key edit-id;
-
- description
- "Represents a list of status responses,
- corresponding to edits in the YANG Patch
- request message. If an edit entry was
- skipped or not reached by the server,
- then this list will not contain a corresponding
- entry for that edit.";
-
- leaf edit-id {
- type string;
- description
- "Response status is for the edit list entry
- with this edit-id value.";
- }
- choice edit-status-choice {
- description
- "A choice between different types of status
- responses for each edit entry.";
- leaf ok {
- type empty;
- description
- "This edit entry was invoked without any
- errors detected by the server associated
- with this edit.";
- }
- leaf location {
- type inet:uri;
- description
- "Contains the Location header value that would be
- returned if this edit causes a new resource to be
- created. If the edit identified by the same edit-id
- value was successfully invoked and a new resource
- was created, then this field will be returned
- instead of 'ok'.";
- }
- case errors {
- uses errors;
- description
- "The server detected errors associated with the
- edit identified by the same edit-id value.";
- }
- }
- }
- }
- }
- } // grouping yang-patch-status
-
-
- grouping errors {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of a
- YANG Patch errors report within a response message.";
-
- container errors {
- config false; // needed so list error does not need a key
- description
- "Represents an error report returned by the server if
- a request results in an error.";
-
- list error {
- description
- "An entry containing information about one
- specific error that occurred while processing
- a RESTCONF request.";
- reference "RFC 6241, Section 4.3";
-
- leaf error-type {
- type enumeration {
- enum transport {
- description "The transport layer";
- }
- enum rpc {
- description "The rpc or notification layer";
- }
- enum protocol {
- description "The protocol operation layer";
- }
- enum application {
- description "The server application layer";
- }
- }
- mandatory true;
- description
- "The protocol layer where the error occurred.";
- }
-
- leaf error-tag {
- type string;
- mandatory true;
- description
- "The enumerated error tag.";
- }
-
- leaf error-app-tag {
- type string;
- description
- "The application-specific error tag.";
- }
-
- leaf error-path {
- type data-resource-identifier;
- description
- "The target data resource identifier associated
- with the error, if any.";
- }
- leaf error-message {
- type string;
- description
- "A message describing the error.";
- }
-
- container error-info {
- description
- "A container allowing additional information
- to be included in the error report.";
- // arbitrary anyxml content here
- }
- }
- }
- } // grouping errors
-
-
- grouping restconf {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of
- the RESTCONF API resource.";
-
- container restconf {
- description
- "Conceptual container representing the
- application/yang.api resource type.";
-
- container config {
- description
- "Container representing the application/yang.datastore
- resource type. Represents the conceptual root of the
- unified configuration datastore containing YANG data
- nodes. The child nodes of this container are
- configuration data resources (application/yang.data)
- defined as top-level YANG data nodes from the modules
- advertised by the server in /restconf/modules.";
- }
-
- container operational {
- description
- "Container representing the application/yang.datastore
- resource type. Represents the conceptual root of the
- operational data supported by the server. The child
- nodes of this container are operational data resources
- (application/yang.data) defined as top-level
- YANG data nodes from the modules advertised by
- the server in /restconf/modules.";
- }
-
- container modules {
- description
- "Contains a list of module description entries.
- These modules are currently loaded into the server.";
-
- list module {
- key "name revision";
- description
- "Each entry represents one module currently
- supported by the server.";
-
- leaf name {
- type yang:yang-identifier;
- description "The YANG module name.";
- }
- leaf revision {
- type union {
- type revision-identifier;
- type string { length 0; }
- }
- description
- "The YANG module revision date. An empty string is
- used if no revision statement is present in the
- YANG module.";
- }
- leaf namespace {
- type inet:uri;
- mandatory true;
- description
- "The XML namespace identifier for this module.";
- }
- leaf-list feature {
- type yang:yang-identifier;
- description
- "List of YANG feature names from this module that are
- supported by the server.";
- }
- leaf-list deviation {
- type yang:yang-identifier;
- description
- "List of YANG deviation module names used by this
- server to modify the conformance of the module
- associated with this entry.";
- }
- }
- }
-
- container operations {
- description
- "Container for all operation resources
- (application/yang.operation),
-
- Each resource is represented as an empty leaf with the
- name of the RPC operation from the YANG rpc statement.
-
- E.g.;
-
- POST /restconf/operations/show-log-errors
-
- leaf show-log-errors {
- type empty;
- }
- ";
- }
-
- container streams {
- description
- "Container representing the notification event streams
- supported by the server.";
- reference
- "RFC 5277, Section 3.4, <streams> element.";
-
- list stream {
- key name;
- description
- "Each entry describes an event stream supported by
- the server.";
-
- leaf name {
- type string;
- description "The stream name";
- reference "RFC 5277, Section 3.4, <name> element.";
- }
-
- leaf description {
- type string;
- description "Description of stream content";
- reference
- "RFC 5277, Section 3.4, <description> element.";
- }
-
- leaf replay-support {
- type boolean;
- description
- "Indicates if replay buffer supported for this stream";
- reference
- "RFC 5277, Section 3.4, <replaySupport> element.";
- }
-
- leaf replay-log-creation-time {
- type yang:date-and-time;
- description
- "Indicates the time the replay log for this stream
- was created.";
- reference
- "RFC 5277, Section 3.4, <replayLogCreationTime>
- element.";
- }
-
- leaf events {
- type empty;
- description
- "Represents the entry point for establishing
- notification delivery via server sent events.";
- }
- }
- }
-
- leaf version {
- type enumeration {
- enum "1.0" {
- description
- "Version 1.0 of the RESTCONF protocol.";
- }
- }
- config false;
- description
- "Contains the RESTCONF protocol version.";
- }
- }
- } // grouping restconf
-
-
- grouping notification {
- description
- "Contains the notification message wrapper definition.";
-
- container notification {
- description
- "RESTCONF notification message wrapper.";
- leaf event-time {
- type yang:date-and-time;
- mandatory true;
- description
- "The time the event was generated by the
- event source.";
- reference
- "RFC 5277, section 4, <eventTime> element.";
- }
-
- /* The YANG-specific notification container is encoded
- * after the 'event-time' element. The format
- * corresponds to the notificationContent element
- * in RFC 5277, section 4. For example:
- *
- * module example-one {
- * ...
- * notification event1 { ... }
- *
- * }
- *
- * Encoded as element 'event1' in the namespace
- * for module 'example-one'.
- */
- }
- } // grouping notification
-
- }
\ No newline at end of file
+++ /dev/null
-module ietf-yang-library {
- namespace "urn:ietf:params:xml:ns:yang:ietf-yang-library";
- prefix "yanglib";
- import ietf-yang-types {
- prefix yang;
- }
- import ietf-inet-types {
- prefix inet;
- }
- organization
- "IETF NETCONF (Network Configuration) Working Group";
- contact
- "WG Web: <https://datatracker.ietf.org/wg/netconf/>
- WG List: <mailto:netconf@ietf.org>
- WG Chair: Mehmet Ersue
- <mailto:mehmet.ersue@nsn.com>
- WG Chair: Mahesh Jethanandani
- <mailto:mjethanandani@gmail.com>
- Editor: Andy Bierman
- <mailto:andy@yumaworks.com>
- Editor: Martin Bjorklund
- <mailto:mbj@tail-f.com>
- Editor: Kent Watsen
- <mailto:kwatsen@juniper.net>";
- description
- "This module contains monitoring information about the YANG
- modules and submodules that are used within a YANG-based
- server.
- Copyright (c) 2016 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 7895; see
- the RFC itself for full legal notices.";
- revision 2016-06-21 {
- description
- "Initial revision.";
- reference
- "RFC 7895: YANG Module Library.";
- }
- /*
- * Typedefs
- */
- typedef revision-identifier {
- type string {
- pattern '\d{4}-\d{2}-\d{2}';
- }
- description
- "Represents a specific date in YYYY-MM-DD format.";
- }
- /*
- * Groupings
- */
- grouping module-list {
- description
- "The module data structure is represented as a grouping
- so it can be reused in configuration or another monitoring
- data structure.";
- grouping common-leafs {
- description
- "Common parameters for YANG modules and submodules.";
- leaf name {
- type yang:yang-identifier;
- description
- "The YANG module or submodule name.";
- }
- leaf revision {
- type union {
- type revision-identifier;
- type string { length 0; }
- }
- description
- "The YANG module or submodule revision date.
- A zero-length string is used if no revision statement
- is present in the YANG module or submodule.";
- }
- }
- grouping schema-leaf {
- description
- "Common schema leaf parameter for modules and submodules.";
- leaf schema {
- type inet:uri;
- description
- "Contains a URL that represents the YANG schema
- resource for this module or submodule.
- This leaf will only be present if there is a URL
- available for retrieval of the schema for this entry.";
- }
- }
- list module {
- key "name revision";
- description
- "Each entry represents one revision of one module
- currently supported by the server.";
- uses common-leafs;
- uses schema-leaf;
- leaf namespace {
- type inet:uri;
- mandatory true;
- description
- "The XML namespace identifier for this module.";
- }
- leaf-list feature {
- type yang:yang-identifier;
- description
- "List of YANG feature names from this module that are
- supported by the server, regardless of whether they are
- defined in the module or any included submodule.";
- }
- list deviation {
- key "name revision";
- description
- "List of YANG deviation module names and revisions
- used by this server to modify the conformance of
- the module associated with this entry. Note that
- the same module can be used for deviations for
- multiple modules, so the same entry MAY appear
- within multiple 'module' entries.
- The deviation module MUST be present in the 'module'
- list, with the same name and revision values.
- The 'conformance-type' value will be 'implement' for
- the deviation module.";
- uses common-leafs;
- }
- leaf conformance-type {
- type enumeration {
- enum implement {
- description
- "Indicates that the server implements one or more
- protocol-accessible objects defined in the YANG module
- identified in this entry. This includes deviation
- statements defined in the module.
- For YANG version 1.1 modules, there is at most one
- module entry with conformance type 'implement' for a
- particular module name, since YANG 1.1 requires that,
- at most, one revision of a module is implemented.
- For YANG version 1 modules, there SHOULD NOT be more
- than one module entry for a particular module name.";
- }
- enum import {
- description
- "Indicates that the server imports reusable definitions
- from the specified revision of the module but does
- not implement any protocol-accessible objects from
- this revision.
- Multiple module entries for the same module name MAY
- exist. This can occur if multiple modules import the
- same module but specify different revision dates in
- the import statements.";
- }
- }
- mandatory true;
- description
- "Indicates the type of conformance the server is claiming
- for the YANG module identified by this entry.";
- }
- list submodule {
- key "name revision";
- description
- "Each entry represents one submodule within the
- parent module.";
- uses common-leafs;
- uses schema-leaf;
- }
- }
- }
- /*
- * Operational state data nodes
- */
- container modules-state {
- config false;
- description
- "Contains YANG module monitoring information.";
- leaf module-set-id {
- type string;
- mandatory true;
- description
- "Contains a server-specific identifier representing
- the current set of modules and submodules. The
- server MUST change the value of this leaf if the
- information represented by the 'module' list instances
- has changed.";
- }
- uses module-list;
- }
- /*
- * Notifications
- */
- notification yang-library-change {
- description
- "Generated when the set of modules and submodules supported
- by the server has changed.";
- leaf module-set-id {
- type leafref {
- path "/yanglib:modules-state/yanglib:module-set-id";
- }
- mandatory true;
- description
- "Contains the module-set-id value representing the
- set of modules and submodules supported at the server at
- the time the notification is generated.";
- }
- }
-}
+++ /dev/null
- 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)";
- }
-
- 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 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";
- }
-
- }
+++ /dev/null
-module module1 {
- namespace "module:1";
- prefix "mod1";
- revision "2014-01-01";
-
- rpc dummy-rpc1-module1 {
- }
-
- rpc dummy-rpc2-module1 {
- }
-
-}
\ No newline at end of file
+++ /dev/null
-module module2 {
- namespace "module:2";
- prefix "mod2";
- revision "2014-01-02";
-
- rpc dummy-rpc1-module2 {
- }
-
- rpc dummy-rpc2-module2 {
- }
-}
\ No newline at end of file
+++ /dev/null
-module module3 {
- namespace "module:3";
- prefix "mod3";
- revision "2014-01-03";
-}
\ No newline at end of file
+++ /dev/null
-module iana-if-type {
- namespace "urn:ietf:params:xml:ns:yang:iana-if-type";
- prefix ianaift;
-
- organization "IANA";
- contact
- " Internet Assigned Numbers Authority
-
- Postal: ICANN
- 4676 Admiralty Way, Suite 330
- Marina del Rey, CA 90292
-
- Tel: +1 310 823 9358
- E-Mail: iana&iana.org";
- description
- "This YANG module defines the iana-if-type typedef, which
- contains YANG definitions for IANA-registered interface types.
-
- This YANG module is maintained by IANA, and reflects the
- 'ifType definitions' registry.
-
- The latest revision of this YANG module can be obtained from
- the IANA web site.
-
- Copyright (c) 2011 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 XXXX; see
- the RFC itself for full legal notices.";
- // RFC Ed.: replace XXXX with actual RFC number and remove this
- // note.
-
- // RFC Ed.: update the date below with the date of RFC publication
- // and remove this note.
- revision 2013-07-04 {
- description
- "Initial revision.";
- reference
- "RFC XXXX: IANA Interface Type YANG Module";
- }
-
- typedef iana-if-type {
- type enumeration {
- enum "other" {
- value 1;
- description
- "None of the following";
- }
- enum "regular1822" {
- value 2;
- }
- enum "hdh1822" {
- value 3;
- }
- enum "ddnX25" {
- value 4;
- }
- enum "rfc877x25" {
- value 5;
- reference
- "RFC 1382 - SNMP MIB Extension for the X.25 Packet Layer";
- }
- enum "ethernetCsmacd" {
- value 6;
- description
- "For all ethernet-like interfaces, regardless of speed,
- as per RFC3635.";
- reference
- "RFC 3635 - Definitions of Managed Objects for the
- Ethernet-like Interface Types.";
- }
- enum "iso88023Csmacd" {
- value 7;
- status deprecated;
- description
- "Deprecated via RFC3635.
- Use ethernetCsmacd(6) instead.";
- reference
- "RFC 3635 - Definitions of Managed Objects for the
- Ethernet-like Interface Types.";
- }
- enum "iso88024TokenBus" {
- value 8;
- }
- enum "iso88025TokenRing" {
- value 9;
- }
- enum "iso88026Man" {
- value 10;
- }
- enum "starLan" {
- value 11;
- status deprecated;
- description
- "Deprecated via RFC3635.
- Use ethernetCsmacd(6) instead.";
- reference
- "RFC 3635 - Definitions of Managed Objects for the
- Ethernet-like Interface Types.";
- }
- enum "proteon10Mbit" {
- value 12;
- }
- enum "proteon80Mbit" {
- value 13;
- }
- enum "hyperchannel" {
- value 14;
- }
- enum "fddi" {
- value 15;
- reference
- "RFC 1512 - FDDI Management Information Base";
- }
- enum "lapb" {
- value 16;
- reference
- "RFC 1381 - SNMP MIB Extension for X.25 LAPB";
- }
- enum "sdlc" {
- value 17;
- }
- enum "ds1" {
- value 18;
- description
- "DS1-MIB";
- reference
- "RFC 4805 - Definitions of Managed Objects for the
- DS1, J1, E1, DS2, and E2 Interface Types";
- }
- enum "e1" {
- value 19;
- status obsolete;
- description
- "Obsolete see DS1-MIB";
- reference
- "RFC 4805 - Definitions of Managed Objects for the
- DS1, J1, E1, DS2, and E2 Interface Types";
- }
- enum "basicISDN" {
- value 20;
- description
- "see also RFC2127";
- }
- enum "primaryISDN" {
- value 21;
- }
- enum "propPointToPointSerial" {
- value 22;
- description
- "proprietary serial";
- }
- enum "ppp" {
- value 23;
- }
- enum "softwareLoopback" {
- value 24;
- }
- enum "eon" {
- value 25;
- description
- "CLNP over IP";
- }
- enum "ethernet3Mbit" {
- value 26;
- }
- enum "nsip" {
- value 27;
- description
- "XNS over IP";
- }
- enum "slip" {
- value 28;
- description
- "generic SLIP";
- }
- enum "ultra" {
- value 29;
- description
- "ULTRA technologies";
- }
- enum "ds3" {
- value 30;
- description
- "DS3-MIB";
- reference
- "RFC 3896 - Definitions of Managed Objects for the
- DS3/E3 Interface Type";
- }
- enum "sip" {
- value 31;
- description
- "SMDS, coffee";
- reference
- "RFC 1694 - Definitions of Managed Objects for SMDS
- Interfaces using SMIv2";
- }
- enum "frameRelay" {
- value 32;
- description
- "DTE only.";
- reference
- "RFC 2115 - Management Information Base for Frame Relay
- DTEs Using SMIv2";
- }
- enum "rs232" {
- value 33;
- reference
- "RFC 1659 - Definitions of Managed Objects for RS-232-like
- Hardware Devices using SMIv2";
- }
- enum "para" {
- value 34;
- description
- "parallel-port";
- reference
- "RFC 1660 - Definitions of Managed Objects for
- Parallel-printer-like Hardware Devices using
- SMIv2";
- }
- enum "arcnet" {
- value 35;
- description
- "arcnet";
- }
- enum "arcnetPlus" {
- value 36;
- description
- "arcnet plus";
- }
- enum "atm" {
- value 37;
- description
- "ATM cells";
- }
- enum "miox25" {
- value 38;
- reference
- "RFC 1461 - SNMP MIB extension for Multiprotocol
- Interconnect over X.25";
- }
- enum "sonet" {
- value 39;
- description
- "SONET or SDH";
- }
- enum "x25ple" {
- value 40;
- reference
- "RFC 2127 - ISDN Management Information Base using SMIv2";
- }
- enum "iso88022llc" {
- value 41;
- }
- enum "localTalk" {
- value 42;
- }
- enum "smdsDxi" {
- value 43;
- }
- enum "frameRelayService" {
- value 44;
- description
- "FRNETSERV-MIB";
- reference
- "RFC 2954 - Definitions of Managed Objects for Frame
- Relay Service";
- }
- enum "v35" {
- value 45;
- }
- enum "hssi" {
- value 46;
- }
- enum "hippi" {
- value 47;
- }
- enum "modem" {
- value 48;
- description
- "Generic modem";
- }
- enum "aal5" {
- value 49;
- description
- "AAL5 over ATM";
- }
- enum "sonetPath" {
- value 50;
- }
- enum "sonetVT" {
- value 51;
- }
- enum "smdsIcip" {
- value 52;
- description
- "SMDS InterCarrier Interface";
- }
- enum "propVirtual" {
- value 53;
- description
- "proprietary virtual/internal";
- reference
- "RFC 2863 - The Interfaces Group MIB";
- }
- enum "propMultiplexor" {
- value 54;
- description
- "proprietary multiplexing";
- reference
- "RFC 2863 - The Interfaces Group MIB";
- }
- enum "ieee80212" {
- value 55;
- description
- "100BaseVG";
- }
- enum "fibreChannel" {
- value 56;
- description
- "Fibre Channel";
- }
- enum "hippiInterface" {
- value 57;
- description
- "HIPPI interfaces";
- }
- enum "frameRelayInterconnect" {
- value 58;
- status obsolete;
- description
- "Obsolete use either
- frameRelay(32) or frameRelayService(44).";
- }
- enum "aflane8023" {
- value 59;
- description
- "ATM Emulated LAN for 802.3";
- }
- enum "aflane8025" {
- value 60;
- description
- "ATM Emulated LAN for 802.5";
- }
- enum "cctEmul" {
- value 61;
- description
- "ATM Emulated circuit";
- }
- enum "fastEther" {
- value 62;
- status deprecated;
- description
- "Obsoleted via RFC3635.
- ethernetCsmacd(6) should be used instead";
- reference
- "RFC 3635 - Definitions of Managed Objects for the
- Ethernet-like Interface Types.";
- }
- enum "isdn" {
- value 63;
- description
- "ISDN and X.25";
- reference
- "RFC 1356 - Multiprotocol Interconnect on X.25 and ISDN
- in the Packet Mode";
- }
- enum "v11" {
- value 64;
- description
- "CCITT V.11/X.21";
- }
- enum "v36" {
- value 65;
- description
- "CCITT V.36";
- }
- enum "g703at64k" {
- value 66;
- description
- "CCITT G703 at 64Kbps";
- }
- enum "g703at2mb" {
- value 67;
- status obsolete;
- description
- "Obsolete see DS1-MIB";
- }
- enum "qllc" {
- value 68;
- description
- "SNA QLLC";
- }
- enum "fastEtherFX" {
- value 69;
- status deprecated;
- description
- "Obsoleted via RFC3635
- ethernetCsmacd(6) should be used instead";
- reference
- "RFC 3635 - Definitions of Managed Objects for the
- Ethernet-like Interface Types.";
- }
- enum "channel" {
- value 70;
- description
- "channel";
- }
- enum "ieee80211" {
- value 71;
- description
- "radio spread spectrum";
- }
- enum "ibm370parChan" {
- value 72;
- description
- "IBM System 360/370 OEMI Channel";
- }
- enum "escon" {
- value 73;
- description
- "IBM Enterprise Systems Connection";
- }
- enum "dlsw" {
- value 74;
- description
- "Data Link Switching";
- }
- enum "isdns" {
- value 75;
- description
- "ISDN S/T interface";
- }
- enum "isdnu" {
- value 76;
- description
- "ISDN U interface";
- }
- enum "lapd" {
- value 77;
- description
- "Link Access Protocol D";
- }
- enum "ipSwitch" {
- value 78;
- description
- "IP Switching Objects";
- }
- enum "rsrb" {
- value 79;
- description
- "Remote Source Route Bridging";
- }
- enum "atmLogical" {
- value 80;
- description
- "ATM Logical Port";
- reference
- "RFC 3606 - Definitions of Supplemental Managed Objects
- for ATM Interface";
- }
- enum "ds0" {
- value 81;
- description
- "Digital Signal Level 0";
- reference
- "RFC 2494 - Definitions of Managed Objects for the DS0
- and DS0 Bundle Interface Type";
- }
- enum "ds0Bundle" {
- value 82;
- description
- "group of ds0s on the same ds1";
- reference
- "RFC 2494 - Definitions of Managed Objects for the DS0
- and DS0 Bundle Interface Type";
- }
- enum "bsc" {
- value 83;
- description
- "Bisynchronous Protocol";
- }
- enum "async" {
- value 84;
- description
- "Asynchronous Protocol";
- }
- enum "cnr" {
- value 85;
- description
- "Combat Net Radio";
- }
- enum "iso88025Dtr" {
- value 86;
- description
- "ISO 802.5r DTR";
- }
- enum "eplrs" {
- value 87;
- description
- "Ext Pos Loc Report Sys";
- }
- enum "arap" {
- value 88;
- description
- "Appletalk Remote Access Protocol";
- }
- enum "propCnls" {
- value 89;
- description
- "Proprietary Connectionless Protocol";
- }
- enum "hostPad" {
- value 90;
- description
- "CCITT-ITU X.29 PAD Protocol";
- }
- enum "termPad" {
- value 91;
- description
- "CCITT-ITU X.3 PAD Facility";
- }
- enum "frameRelayMPI" {
- value 92;
- description
- "Multiproto Interconnect over FR";
- }
- enum "x213" {
- value 93;
- description
- "CCITT-ITU X213";
- }
- enum "adsl" {
- value 94;
- description
- "Asymmetric Digital Subscriber Loop";
- }
- enum "radsl" {
- value 95;
- description
- "Rate-Adapt. Digital Subscriber Loop";
- }
- enum "sdsl" {
- value 96;
- description
- "Symmetric Digital Subscriber Loop";
- }
- enum "vdsl" {
- value 97;
- description
- "Very H-Speed Digital Subscrib. Loop";
- }
- enum "iso88025CRFPInt" {
- value 98;
- description
- "ISO 802.5 CRFP";
- }
- enum "myrinet" {
- value 99;
- description
- "Myricom Myrinet";
- }
- enum "voiceEM" {
- value 100;
- description
- "voice recEive and transMit";
- }
- enum "voiceFXO" {
- value 101;
- description
- "voice Foreign Exchange Office";
- }
- enum "voiceFXS" {
- value 102;
- description
- "voice Foreign Exchange Station";
- }
- enum "voiceEncap" {
- value 103;
- description
- "voice encapsulation";
- }
- enum "voiceOverIp" {
- value 104;
- description
- "voice over IP encapsulation";
- }
- enum "atmDxi" {
- value 105;
- description
- "ATM DXI";
- }
- enum "atmFuni" {
- value 106;
- description
- "ATM FUNI";
- }
- enum "atmIma" {
- value 107;
- description
- "ATM IMA";
- }
- enum "pppMultilinkBundle" {
- value 108;
- description
- "PPP Multilink Bundle";
- }
- enum "ipOverCdlc" {
- value 109;
- description
- "IBM ipOverCdlc";
- }
- enum "ipOverClaw" {
- value 110;
- description
- "IBM Common Link Access to Workstn";
- }
- enum "stackToStack" {
- value 111;
- description
- "IBM stackToStack";
- }
- enum "virtualIpAddress" {
- value 112;
- description
- "IBM VIPA";
- }
- enum "mpc" {
- value 113;
- description
- "IBM multi-protocol channel support";
- }
- enum "ipOverAtm" {
- value 114;
- description
- "IBM ipOverAtm";
- reference
- "RFC 2320 - Definitions of Managed Objects for Classical IP
- and ARP Over ATM Using SMIv2 (IPOA-MIB)";
- }
- enum "iso88025Fiber" {
- value 115;
- description
- "ISO 802.5j Fiber Token Ring";
- }
- enum "tdlc" {
- value 116;
- description
- "IBM twinaxial data link control";
- }
- enum "gigabitEthernet" {
- value 117;
- status deprecated;
- description
- "Obsoleted via RFC3635
- ethernetCsmacd(6) should be used instead";
- reference
- "RFC 3635 - Definitions of Managed Objects for the
- Ethernet-like Interface Types.";
- }
- enum "hdlc" {
- value 118;
- description
- "HDLC";
- }
- enum "lapf" {
- value 119;
- description
- "LAP F";
- }
- enum "v37" {
- value 120;
- description
- "V.37";
- }
- enum "x25mlp" {
- value 121;
- description
- "Multi-Link Protocol";
- }
- enum "x25huntGroup" {
- value 122;
- description
- "X25 Hunt Group";
- }
- enum "transpHdlc" {
- value 123;
- description
- "Transp HDLC";
- }
- enum "interleave" {
- value 124;
- description
- "Interleave channel";
- }
- enum "fast" {
- value 125;
- description
- "Fast channel";
- }
- enum "ip" {
- value 126;
- description
- "IP (for APPN HPR in IP networks)";
- }
- enum "docsCableMaclayer" {
- value 127;
- description
- "CATV Mac Layer";
- }
- enum "docsCableDownstream" {
- value 128;
- description
- "CATV Downstream interface";
- }
- enum "docsCableUpstream" {
- value 129;
- description
- "CATV Upstream interface";
- }
- enum "a12MppSwitch" {
- value 130;
- description
- "Avalon Parallel Processor";
- }
- enum "tunnel" {
- value 131;
- description
- "Encapsulation interface";
- }
- enum "coffee" {
- value 132;
- description
- "coffee pot";
- reference
- "RFC 2325 - Coffee MIB";
- }
- enum "ces" {
- value 133;
- description
- "Circuit Emulation Service";
- }
- enum "atmSubInterface" {
- value 134;
- description
- "ATM Sub Interface";
- }
- enum "l2vlan" {
- value 135;
- description
- "Layer 2 Virtual LAN using 802.1Q";
- }
- enum "l3ipvlan" {
- value 136;
- description
- "Layer 3 Virtual LAN using IP";
- }
- enum "l3ipxvlan" {
- value 137;
- description
- "Layer 3 Virtual LAN using IPX";
- }
- enum "digitalPowerline" {
- value 138;
- description
- "IP over Power Lines";
- }
- enum "mediaMailOverIp" {
- value 139;
- description
- "Multimedia Mail over IP";
- }
- enum "dtm" {
- value 140;
- description
- "Dynamic syncronous Transfer Mode";
- }
- enum "dcn" {
- value 141;
- description
- "Data Communications Network";
- }
- enum "ipForward" {
- value 142;
- description
- "IP Forwarding Interface";
- }
- enum "msdsl" {
- value 143;
- description
- "Multi-rate Symmetric DSL";
- }
- enum "ieee1394" {
- value 144;
- description
- "IEEE1394 High Performance Serial Bus";
- }
- enum "if-gsn" {
- value 145;
- description
- "HIPPI-6400";
- }
- enum "dvbRccMacLayer" {
- value 146;
- description
- "DVB-RCC MAC Layer";
- }
- enum "dvbRccDownstream" {
- value 147;
- description
- "DVB-RCC Downstream Channel";
- }
- enum "dvbRccUpstream" {
- value 148;
- description
- "DVB-RCC Upstream Channel";
- }
- enum "atmVirtual" {
- value 149;
- description
- "ATM Virtual Interface";
- }
- enum "mplsTunnel" {
- value 150;
- description
- "MPLS Tunnel Virtual Interface";
- }
- enum "srp" {
- value 151;
- description
- "Spatial Reuse Protocol";
- }
- enum "voiceOverAtm" {
- value 152;
- description
- "Voice Over ATM";
- }
- enum "voiceOverFrameRelay" {
- value 153;
- description
- "Voice Over Frame Relay";
- }
- enum "idsl" {
- value 154;
- description
- "Digital Subscriber Loop over ISDN";
- }
- enum "compositeLink" {
- value 155;
- description
- "Avici Composite Link Interface";
- }
- enum "ss7SigLink" {
- value 156;
- description
- "SS7 Signaling Link";
- }
- enum "propWirelessP2P" {
- value 157;
- description
- "Prop. P2P wireless interface";
- }
- enum "frForward" {
- value 158;
- description
- "Frame Forward Interface";
- }
- enum "rfc1483" {
- value 159;
- description
- "Multiprotocol over ATM AAL5";
- reference
- "RFC 1483 - Multiprotocol Encapsulation over ATM
- Adaptation Layer 5";
- }
- enum "usb" {
- value 160;
- description
- "USB Interface";
- }
- enum "ieee8023adLag" {
- value 161;
- description
- "IEEE 802.3ad Link Aggregate";
- }
- enum "bgppolicyaccounting" {
- value 162;
- description
- "BGP Policy Accounting";
- }
- enum "frf16MfrBundle" {
- value 163;
- description
- "FRF .16 Multilink Frame Relay";
- }
- enum "h323Gatekeeper" {
- value 164;
- description
- "H323 Gatekeeper";
- }
- enum "h323Proxy" {
- value 165;
- description
- "H323 Voice and Video Proxy";
- }
- enum "mpls" {
- value 166;
- description
- "MPLS";
- }
- enum "mfSigLink" {
- value 167;
- description
- "Multi-frequency signaling link";
- }
- enum "hdsl2" {
- value 168;
- description
- "High Bit-Rate DSL - 2nd generation";
- }
- enum "shdsl" {
- value 169;
- description
- "Multirate HDSL2";
- }
- enum "ds1FDL" {
- value 170;
- description
- "Facility Data Link 4Kbps on a DS1";
- }
- enum "pos" {
- value 171;
- description
- "Packet over SONET/SDH Interface";
- }
- enum "dvbAsiIn" {
- value 172;
- description
- "DVB-ASI Input";
- }
- enum "dvbAsiOut" {
- value 173;
- description
- "DVB-ASI Output";
- }
- enum "plc" {
- value 174;
- description
- "Power Line Communtications";
- }
- enum "nfas" {
- value 175;
- description
- "Non Facility Associated Signaling";
- }
- enum "tr008" {
- value 176;
- description
- "TR008";
- }
- enum "gr303RDT" {
- value 177;
- description
- "Remote Digital Terminal";
- }
- enum "gr303IDT" {
- value 178;
- description
- "Integrated Digital Terminal";
- }
- enum "isup" {
- value 179;
- description
- "ISUP";
- }
- enum "propDocsWirelessMaclayer" {
- value 180;
- description
- "Cisco proprietary Maclayer";
- }
- enum "propDocsWirelessDownstream" {
- value 181;
- description
- "Cisco proprietary Downstream";
- }
- enum "propDocsWirelessUpstream" {
- value 182;
- description
- "Cisco proprietary Upstream";
- }
- enum "hiperlan2" {
- value 183;
- description
- "HIPERLAN Type 2 Radio Interface";
- }
- enum "propBWAp2Mp" {
- value 184;
- description
- "PropBroadbandWirelessAccesspt2multipt use of this value
- for IEEE 802.16 WMAN interfaces as per IEEE Std 802.16f
- is deprecated and ieee80216WMAN(237) should be used
- instead.";
- }
- enum "sonetOverheadChannel" {
- value 185;
- description
- "SONET Overhead Channel";
- }
- enum "digitalWrapperOverheadChannel" {
- value 186;
- description
- "Digital Wrapper";
- }
- enum "aal2" {
- value 187;
- description
- "ATM adaptation layer 2";
- }
- enum "radioMAC" {
- value 188;
- description
- "MAC layer over radio links";
- }
- enum "atmRadio" {
- value 189;
- description
- "ATM over radio links";
- }
- enum "imt" {
- value 190;
- description
- "Inter Machine Trunks";
- }
- enum "mvl" {
- value 191;
- description
- "Multiple Virtual Lines DSL";
- }
- enum "reachDSL" {
- value 192;
- description
- "Long Reach DSL";
- }
- enum "frDlciEndPt" {
- value 193;
- description
- "Frame Relay DLCI End Point";
- }
- enum "atmVciEndPt" {
- value 194;
- description
- "ATM VCI End Point";
- }
- enum "opticalChannel" {
- value 195;
- description
- "Optical Channel";
- }
- enum "opticalTransport" {
- value 196;
- description
- "Optical Transport";
- }
- enum "propAtm" {
- value 197;
- description
- "Proprietary ATM";
- }
- enum "voiceOverCable" {
- value 198;
- description
- "Voice Over Cable Interface";
- }
- enum "infiniband" {
- value 199;
- description
- "Infiniband";
- }
- enum "teLink" {
- value 200;
- description
- "TE Link";
- }
- enum "q2931" {
- value 201;
- description
- "Q.2931";
- }
- enum "virtualTg" {
- value 202;
- description
- "Virtual Trunk Group";
- }
- enum "sipTg" {
- value 203;
- description
- "SIP Trunk Group";
- }
- enum "sipSig" {
- value 204;
- description
- "SIP Signaling";
- }
- enum "docsCableUpstreamChannel" {
- value 205;
- description
- "CATV Upstream Channel";
- }
- enum "econet" {
- value 206;
- description
- "Acorn Econet";
- }
- enum "pon155" {
- value 207;
- description
- "FSAN 155Mb Symetrical PON interface";
- }
- enum "pon622" {
- value 208;
- description
- "FSAN622Mb Symetrical PON interface";
- }
- enum "bridge" {
- value 209;
- description
- "Transparent bridge interface";
- }
- enum "linegroup" {
- value 210;
- description
- "Interface common to multiple lines";
- }
- enum "voiceEMFGD" {
- value 211;
- description
- "voice E&M Feature Group D";
- }
- enum "voiceFGDEANA" {
- value 212;
- description
- "voice FGD Exchange Access North American";
- }
- enum "voiceDID" {
- value 213;
- description
- "voice Direct Inward Dialing";
- }
- enum "mpegTransport" {
- value 214;
- description
- "MPEG transport interface";
- }
- enum "sixToFour" {
- value 215;
- status deprecated;
- description
- "6to4 interface (DEPRECATED)";
- reference
- "RFC 4087 - IP Tunnel MIB";
- }
- enum "gtp" {
- value 216;
- description
- "GTP (GPRS Tunneling Protocol)";
- }
- enum "pdnEtherLoop1" {
- value 217;
- description
- "Paradyne EtherLoop 1";
- }
- enum "pdnEtherLoop2" {
- value 218;
- description
- "Paradyne EtherLoop 2";
- }
- enum "opticalChannelGroup" {
- value 219;
- description
- "Optical Channel Group";
- }
- enum "homepna" {
- value 220;
- description
- "HomePNA ITU-T G.989";
- }
- enum "gfp" {
- value 221;
- description
- "Generic Framing Procedure (GFP)";
- }
- enum "ciscoISLvlan" {
- value 222;
- description
- "Layer 2 Virtual LAN using Cisco ISL";
- }
- enum "actelisMetaLOOP" {
- value 223;
- description
- "Acteleis proprietary MetaLOOP High Speed Link";
- }
- enum "fcipLink" {
- value 224;
- description
- "FCIP Link";
- }
- enum "rpr" {
- value 225;
- description
- "Resilient Packet Ring Interface Type";
- }
- enum "qam" {
- value 226;
- description
- "RF Qam Interface";
- }
- enum "lmp" {
- value 227;
- description
- "Link Management Protocol";
- reference
- "RFC 4327 - Link Management Protocol (LMP) Management
- Information Base (MIB)";
- }
- enum "cblVectaStar" {
- value 228;
- description
- "Cambridge Broadband Networks Limited VectaStar";
- }
- enum "docsCableMCmtsDownstream" {
- value 229;
- description
- "CATV Modular CMTS Downstream Interface";
- }
- enum "adsl2" {
- value 230;
- status deprecated;
- description
- "Asymmetric Digital Subscriber Loop Version 2
- (DEPRECATED/OBSOLETED - please use adsl2plus(238)
- instead)";
- reference
- "RFC 4706 - Definitions of Managed Objects for Asymmetric
- Digital Subscriber Line 2 (ADSL2)";
- }
- enum "macSecControlledIF" {
- value 231;
- description
- "MACSecControlled";
- }
- enum "macSecUncontrolledIF" {
- value 232;
- description
- "MACSecUncontrolled";
- }
- enum "aviciOpticalEther" {
- value 233;
- description
- "Avici Optical Ethernet Aggregate";
- }
- enum "atmbond" {
- value 234;
- description
- "atmbond";
- }
- enum "voiceFGDOS" {
- value 235;
- description
- "voice FGD Operator Services";
- }
- enum "mocaVersion1" {
- value 236;
- description
- "MultiMedia over Coax Alliance (MoCA) Interface
- as documented in information provided privately to IANA";
- }
- enum "ieee80216WMAN" {
- value 237;
- description
- "IEEE 802.16 WMAN interface";
- }
- enum "adsl2plus" {
- value 238;
- description
- "Asymmetric Digital Subscriber Loop Version 2,
- Version 2 Plus and all variants";
- }
- enum "dvbRcsMacLayer" {
- value 239;
- description
- "DVB-RCS MAC Layer";
- reference
- "RFC 5728 - The SatLabs Group DVB-RCS MIB";
- }
- enum "dvbTdm" {
- value 240;
- description
- "DVB Satellite TDM";
- reference
- "RFC 5728 - The SatLabs Group DVB-RCS MIB";
- }
- enum "dvbRcsTdma" {
- value 241;
- description
- "DVB-RCS TDMA";
- reference
- "RFC 5728 - The SatLabs Group DVB-RCS MIB";
- }
- enum "x86Laps" {
- value 242;
- description
- "LAPS based on ITU-T X.86/Y.1323";
- }
- enum "wwanPP" {
- value 243;
- description
- "3GPP WWAN";
- }
- enum "wwanPP2" {
- value 244;
- description
- "3GPP2 WWAN";
- }
- enum "voiceEBS" {
- value 245;
- description
- "voice P-phone EBS physical interface";
- }
- enum "ifPwType" {
- value 246;
- description
- "Pseudowire interface type";
- reference
- "RFC 5601 - Pseudowire (PW) Management Information Base";
- }
- enum "ilan" {
- value 247;
- description
- "Internal LAN on a bridge per IEEE 802.1ap";
- }
- enum "pip" {
- value 248;
- description
- "Provider Instance Port on a bridge per IEEE 802.1ah PBB";
- }
- enum "aluELP" {
- value 249;
- description
- "Alcatel-Lucent Ethernet Link Protection";
- }
- enum "gpon" {
- value 250;
- description
- "Gigabit-capable passive optical networks (G-PON) as per
- ITU-T G.948";
- }
- enum "vdsl2" {
- value 251;
- description
- "Very high speed digital subscriber line Version 2
- (as per ITU-T Recommendation G.993.2)";
- reference
- "RFC 5650 - Definitions of Managed Objects for Very High
- Speed Digital Subscriber Line 2 (VDSL2)";
- }
- enum "capwapDot11Profile" {
- value 252;
- description
- "WLAN Profile Interface";
- reference
- "RFC 5834 - Control and Provisioning of Wireless Access
- Points (CAPWAP) Protocol Binding MIB for
- IEEE 802.11";
- }
- enum "capwapDot11Bss" {
- value 253;
- description
- "WLAN BSS Interface";
- reference
- "RFC 5834 - Control and Provisioning of Wireless Access
- Points (CAPWAP) Protocol Binding MIB for
- IEEE 802.11";
- }
- enum "capwapWtpVirtualRadio" {
- value 254;
- description
- "WTP Virtual Radio Interface";
- reference
- "RFC 5833 - Control and Provisioning of Wireless Access
- Points (CAPWAP) Protocol Base MIB";
- }
- enum "bits" {
- value 255;
- description
- "bitsport";
- }
- enum "docsCableUpstreamRfPort" {
- value 256;
- description
- "DOCSIS CATV Upstream RF Port";
- }
- enum "cableDownstreamRfPort" {
- value 257;
- description
- "CATV downstream RF port";
- }
- enum "vmwareVirtualNic" {
- value 258;
- description
- "VMware Virtual Network Interface";
- }
- enum "ieee802154" {
- value 259;
- description
- "IEEE 802.15.4 WPAN interface";
- reference
- "IEEE 802.15.4-2006";
- }
- enum "otnOdu" {
- value 260;
- description
- "OTN Optical Data Unit";
- }
- enum "otnOtu" {
- value 261;
- description
- "OTN Optical channel Transport Unit";
- }
- enum "ifVfiType" {
- value 262;
- description
- "VPLS Forwarding Instance Interface Type";
- }
- enum "g9981" {
- value 263;
- description
- "G.998.1 bonded interface";
- }
- enum "g9982" {
- value 264;
- description
- "G.998.2 bonded interface";
- }
- enum "g9983" {
- value 265;
- description
- "G.998.3 bonded interface";
- }
- enum "aluEpon" {
- value 266;
- description
- "Ethernet Passive Optical Networks (E-PON)";
- }
- enum "aluEponOnu" {
- value 267;
- description
- "EPON Optical Network Unit";
- }
- enum "aluEponPhysicalUni" {
- value 268;
- description
- "EPON physical User to Network interface";
- }
- enum "aluEponLogicalLink" {
- value 269;
- description
- "The emulation of a point-to-point link over the EPON
- layer";
- }
- enum "aluGponOnu" {
- value 270;
- description
- "GPON Optical Network Unit";
- reference
- "ITU-T G.984.2";
- }
- enum "aluGponPhysicalUni" {
- value 271;
- description
- "GPON physical User to Network interface";
- reference
- "ITU-T G.984.2";
- }
- enum "vmwareNicTeam" {
- value 272;
- description
- "VMware NIC Team";
- }
- // value 273 reserved by IANA
- }
- description
- "This data type is used as the syntax of the 'type'
- leaf in the 'interface' list in the YANG module
- ietf-interface.
-
- The definition of this typedef with the
- addition of newly assigned values is published
- periodically by the IANA, in either the Assigned
- Numbers RFC, or some derivative of it specific to
- Internet Network Management number assignments. (The
- latest arrangements can be obtained by contacting the
- IANA.)
-
- Requests for new values should be made to IANA via
- email (iana&iana.org).";
- reference
- "IANA ifType definitions registry.
- <http://www.iana.org/assignments/smi-numbers>";
- }
-}
\ No newline at end of file
+++ /dev/null
- 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)";
- }
-
- }
+++ /dev/null
-module ietf-interfaces {
-
- namespace "urn:ietf:params:xml:ns:yang:ietf-interfaces";
- prefix if;
-
- import ietf-yang-types {
- prefix yang;
- }
- import iana-if-type {
- prefix ianaift;
- }
-
- 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: Martin Bjorklund
- <mailto:mbj@tail-f.com>";
-
- description
- "This module contains a collection of YANG definitions for
- managing network interfaces.
-
- 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 XXXX; see
- the RFC itself for full legal notices.";
-
- // RFC Ed.: replace XXXX with actual RFC number and remove this
- // note.
-
- // RFC Ed.: update the date below with the date of RFC publication
- // and remove this note.
- revision 2013-07-04 {
- description
- "Initial revision.";
- reference
- "RFC XXXX: A YANG Data Model for Interface Management";
- }
-
- /* Typedefs */
-
- typedef interface-ref {
- type leafref {
- path "/if:interfaces/if:interface/if:name";
- }
- description
- "This type is used by data models that need to reference
- configured interfaces.";
- }
-
- typedef interface-state-ref {
- type leafref {
- path "/if:interfaces-state/if:interface/if:name";
- }
- description
- "This type is used by data models that need to reference
- the operationally present interfaces.";
- }
-
- /* Features */
-
- feature arbitrary-names {
- description
- "This feature indicates that the device allows user-controlled
- interfaces to be named arbitrarily.";
- }
-
- feature pre-provisioning {
- description
- "This feature indicates that the device supports
- pre-provisioning of interface configuration, i.e., it is
- possible to configure an interface whose physical interface
- hardware is not present on the device.";
- }
-
- feature if-mib {
- description
- "This feature indicates that the device implements IF-MIB.";
- reference
- "RFC 2863: The Interfaces Group MIB";
- }
-
- /* Data nodes */
-
- container interfaces {
- description
- "Interface configuration parameters.";
-
- list interface {
- key "name";
-
- description
- "The list of configured interfaces on the device.
-
- The operational state of an interface is available in the
- /interfaces-state/interface list. If the configuration of a
- system-controlled interface cannot be used by the system
- (e.g., the interface hardware present does not match the
- interface type), then the configuration is not applied to
- the system-controlled interface shown in the
- /interfaces-state/interface list. If the the configuration
- of a user-controlled interface cannot be used by the system,
- the configured interface is not instantiated in the
- /interfaces-state/interface list.";
-
- leaf name {
- type string;
- description
- "The name of the interface.
-
- A device MAY restrict the allowed values for this leaf,
- possibly depending on the type of the interface.
-
- For system-controlled interfaces, this leaf is the
- device-specific name of the interface. The 'config false'
- list /interfaces-state/interface contains the currently
- existing interfaces on the device.
-
- If a client tries to create configuration for a
- system-controlled interface that is not present in the
- /interfaces-state/interface list, the server MAY reject
- the request, if the implementation does not support
- pre-provisioning of interfaces, or if the name refers to
- an interface that can never exist in the system. A
- NETCONF server MUST reply with an rpc-error with the
- error-tag 'invalid-value' in this case.
-
- If the device supports pre-provisioning of interface
- configuration, the feature 'pre-provisioning' is
- advertised.
-
- If the device allows arbitrarily named user-controlled
- interfaces, the feature 'arbitrary-names' is advertised.
-
- When a configured user-controlled interface is created by
- the system, it is instantiated with the same name in the
- /interface-state/interface list. Since the name in that
- list MAY be mapped to ifName by an implementation, such an
- implementation MUST restrict the allowed values for this
- leaf so that it matches the restrictions of ifName.
-
- If a NETCONF server that implements this restriction is
- sent a value that doesn't match the restriction, it MUST
- reply with an rpc-error with the error-tag
- 'invalid-value'.";
- }
-
- leaf description {
- type string;
- description
- "A textual description of the interface.
-
- This leaf MAY be mapped to ifAlias by an implementation.
- Such an implementation MUST restrict the allowed values
- for this leaf so that it matches the restrictions of
- ifAlias.
-
- If a NETCONF server that implements this restriction is
- sent a value that doesn't match the restriction, it MUST
- reply with an rpc-error with the error-tag
- 'invalid-value'.
-
- Since ifAlias is defined to be stored in non-volatile
- storage, the MIB implementation MUST map ifAlias to the
- value of 'description' in the persistently stored
- datastore.
-
- Specifically, if the device supports ':startup', when
- ifAlias is read the device MUST return the value of
- 'description' in the 'startup' datastore, and when it is
- written, it MUST be written to the 'running' and 'startup'
- datastores. Note that it is up to the implementation if
- it modifies this single leaf in 'startup', or if it
- performs an implicit copy-config from 'running' to
- 'startup'.
-
- If the device does not support ':startup', ifAlias MUST
- be mapped to the 'description' leaf in the 'running'
- datastore.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifAlias";
- }
-
- leaf type {
- type ianaift:iana-if-type;
- mandatory true;
- description
- "The type of the interface.
-
- When an interface entry is created, a server MAY
- initialize the type leaf with a valid value, e.g., if it
- is possible to derive the type from the name of the
- interface.
-
- If a client tries to set the type of an interface to a
- value that can never be used by the system, e.g., if the
- type is not supported or if the type does not match the
- name of the interface, the server MUST reject the request.
- A NETCONF server MUST reply with an rpc-error with the
- error-tag 'invalid-value' in this case.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifType";
- }
-
- leaf enabled {
- type boolean;
- default "true";
- description
- "This leaf contains the configured, desired state of the
- interface.
-
- Systems that implement the IF-MIB use the value of this
- leaf in the 'running' datastore to set
- IF-MIB.ifAdminStatus to 'up' or 'down' after an ifEntry
- has been initialized, as described in RFC 2863.
-
- Changes in this leaf in the 'running' datastore are
- reflected in ifAdminStatus, but if ifAdminStatus is
- changed over SNMP, this leaf is not affected.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifAdminStatus";
- }
-
- leaf link-up-down-trap-enable {
- if-feature if-mib;
- type enumeration {
- enum enabled {
- value 1;
- }
- enum disabled {
- value 2;
- }
- }
- description
- "Controls whether linkUp/linkDown SNMP notifications
- should be generated for this interface.
-
- If this node is not configured, the value 'enabled' is
- operationally used by the server for interfaces which do
- not operate on top of any other interface (i.e., there are
- no 'lower-layer-if' entries), and 'disabled' otherwise.";
- reference
- "RFC 2863: The Interfaces Group MIB -
- ifLinkUpDownTrapEnable";
- }
- }
- }
-
- container interfaces-state {
- config false;
- description
- "Data nodes for the operational state of interfaces.";
-
- list interface {
- key "name";
-
- description
- "The list of interfaces on the device.
-
- System-controlled interfaces created by the system are
- always present in this list, whether they are configured or
- not.";
-
- leaf name {
- type string;
- description
- "The name of the interface.
-
- This leaf MAY be mapped to ifName by an implementation.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifName";
- }
-
- leaf type {
- type ianaift:iana-if-type;
- mandatory true;
- description
- "The type of the interface.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifType";
- }
-
- leaf admin-status {
- if-feature if-mib;
- type enumeration {
- enum up {
- value 1;
- description
- "Ready to pass packets.";
- }
- enum down {
- value 2;
- description
- "Not ready to pass packets and not in some test mode.";
- }
- enum testing {
- value 3;
- description
- "In some test mode.";
- }
- }
- mandatory true;
- description
- "The desired state of the interface.
-
- This leaf has the same read semantics as ifAdminStatus.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifAdminStatus";
- }
-
- leaf oper-status {
- type enumeration {
- enum up {
- value 1;
- description
- "Ready to pass packets.";
- }
- enum down {
- value 2;
- description
- "The interface does not pass any packets.";
- }
- enum testing {
- value 3;
- description
- "In some test mode. No operational packets can
- be passed.";
- }
- enum unknown {
- value 4;
- description
- "Status cannot be determined for some reason.";
- }
- enum dormant {
- value 5;
- description
- "Waiting for some external event.";
- }
- enum not-present {
- value 6;
- description
- "Some component (typically hardware) is missing.";
- }
- enum lower-layer-down {
- value 7;
- description
- "Down due to state of lower-layer interface(s).";
- }
- }
- mandatory true;
- description
- "The current operational state of the interface.
-
- This leaf has the same semantics as ifOperStatus.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifOperStatus";
- }
-
- leaf last-change {
- type yang:date-and-time;
- description
- "The time the interface entered its current operational
- state. If the current state was entered prior to the
- last re-initialization of the local network management
- subsystem, then this node is not present.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifLastChange";
- }
-
- leaf if-index {
- if-feature if-mib;
- type int32 {
- range "1..2147483647";
- }
- mandatory true;
- description
- "The ifIndex value for the ifEntry represented by this
- interface.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifIndex";
- }
-
- leaf phys-address {
- type yang:phys-address;
- description
- "The interface's address at its protocol sub-layer. For
- example, for an 802.x interface, this object normally
- contains a MAC address. The interface's media-specific
- modules must define the bit and byte ordering and the
- format of the value of this object. For interfaces that do
- not have such an address (e.g., a serial line), this node
- is not present.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifPhysAddress";
- }
-
- leaf-list higher-layer-if {
- type interface-state-ref;
- description
- "A list of references to interfaces layered on top of this
- interface.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifStackTable";
- }
-
- leaf-list lower-layer-if {
- type interface-state-ref;
- description
- "A list of references to interfaces layered underneath this
- interface.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifStackTable";
- }
-
- leaf speed {
- type yang:gauge64;
- units "bits / second";
- description
- "An estimate of the interface's current bandwidth in bits
- per second. For interfaces that do not vary in
- bandwidth or for those where no accurate estimation can
- be made, this node should contain the nominal bandwidth.
- For interfaces that have no concept of bandwidth, this
- node is not present.";
- reference
- "RFC 2863: The Interfaces Group MIB -
- ifSpeed, ifHighSpeed";
- }
-
- container statistics {
- description
- "A collection of interface-related statistics objects.";
-
- leaf discontinuity-time {
- type yang:date-and-time;
- mandatory true;
- description
- "The time on the most recent occasion at which any one or
- more of this interface's counters suffered a
- discontinuity. If no such discontinuities have occurred
- since the last re-initialization of the local management
- subsystem, then this node contains the time the local
- management subsystem re-initialized itself.";
- }
-
- leaf in-octets {
- type yang:counter64;
- description
- "The total number of octets received on the interface,
- including framing characters.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifHCInOctets";
- }
- leaf in-unicast-pkts {
- type yang:counter64;
- description
- "The number of packets, delivered by this sub-layer to a
- higher (sub-)layer, which were not addressed to a
- multicast or broadcast address at this sub-layer.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifHCInUcastPkts";
- }
- leaf in-broadcast-pkts {
- type yang:counter64;
- description
- "The number of packets, delivered by this sub-layer to a
- higher (sub-)layer, which were addressed to a broadcast
- address at this sub-layer.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB -
- ifHCInBroadcastPkts";
- }
- leaf in-multicast-pkts {
- type yang:counter64;
- description
- "The number of packets, delivered by this sub-layer to a
- higher (sub-)layer, which were addressed to a multicast
- address at this sub-layer. For a MAC layer protocol,
- this includes both Group and Functional addresses.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB -
- ifHCInMulticastPkts";
- }
- leaf in-discards {
- type yang:counter32;
- description
- "The number of inbound packets which were chosen to be
- discarded even though no errors had been detected to
- prevent their being deliverable to a higher-layer
- protocol. One possible reason for discarding such a
- packet could be to free up buffer space.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifInDiscards";
- }
- leaf in-errors {
- type yang:counter32;
- description
- "For packet-oriented interfaces, the number of inbound
- packets that contained errors preventing them from being
- deliverable to a higher-layer protocol. For character-
- oriented or fixed-length interfaces, the number of
- inbound transmission units that contained errors
- preventing them from being deliverable to a higher-layer
- protocol.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifInErrors";
- }
- leaf in-unknown-protos {
- type yang:counter32;
- description
- "For packet-oriented interfaces, the number of packets
- received via the interface which were discarded because
- of an unknown or unsupported protocol. For
- character-oriented or fixed-length interfaces that
- support protocol multiplexing the number of transmission
- units received via the interface which were discarded
- because of an unknown or unsupported protocol. For any
- interface that does not support protocol multiplexing,
- this counter is not present.
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifInUnknownProtos";
- }
-
- leaf out-octets {
- type yang:counter64;
- description
- "The total number of octets transmitted out of the
- interface, including framing characters.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifHCOutOctets";
- }
- leaf out-unicast-pkts {
- type yang:counter64;
- description
- "The total number of packets that higher-level protocols
- requested be transmitted, and which were not addressed
- to a multicast or broadcast address at this sub-layer,
- including those that were discarded or not sent.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifHCOutUcastPkts";
- }
- leaf out-broadcast-pkts {
- type yang:counter64;
- description
- "The total number of packets that higher-level protocols
- requested be transmitted, and which were addressed to a
- broadcast address at this sub-layer, including those
- that were discarded or not sent.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB -
- ifHCOutBroadcastPkts";
- }
- leaf out-multicast-pkts {
- type yang:counter64;
- description
- "The total number of packets that higher-level protocols
- requested be transmitted, and which were addressed to a
- multicast address at this sub-layer, including those
- that were discarded or not sent. For a MAC layer
- protocol, this includes both Group and Functional
- addresses.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB -
- ifHCOutMulticastPkts";
- }
- leaf out-discards {
- type yang:counter32;
- description
- "The number of outbound packets which were chosen to be
- discarded even though no errors had been detected to
- prevent their being transmitted. One possible reason
- for discarding such a packet could be to free up buffer
- space.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifOutDiscards";
- }
- leaf out-errors {
- type yang:counter32;
- description
- "For packet-oriented interfaces, the number of outbound
- packets that could not be transmitted because of errors.
- For character-oriented or fixed-length interfaces, the
- number of outbound transmission units that could not be
- transmitted because of errors.
-
- Discontinuities in the value of this counter can occur
- at re-initialization of the management system, and at
- other times as indicated by the value of
- 'discontinuity-time'.";
- reference
- "RFC 2863: The Interfaces Group MIB - ifOutErrors";
- }
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-module ietf-restconf-monitoring {
- namespace "urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring";
- prefix "rcmon";
-
- import ietf-yang-types { prefix yang; }
- import ietf-inet-types { prefix inet; }
-
- organization
- "IETF NETCONF (Network Configuration) Working Group";
-
- contact
- "WG Web: <https://datatracker.ietf.org/wg/netconf/>
- WG List: <mailto:netconf@ietf.org>
-
- Author: Andy Bierman
- <mailto:andy@yumaworks.com>
-
- Author: Martin Bjorklund
- <mailto:mbj@tail-f.com>
-
- Author: Kent Watsen
- <mailto:kwatsen@juniper.net>";
-
- description
- "This module contains monitoring information for the
- RESTCONF protocol.
-
- Copyright (c) 2017 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 8040; see
- the RFC itself for full legal notices.";
-
- revision 2017-01-26 {
- description
- "Initial revision.";
- reference
- "RFC 8040: RESTCONF Protocol.";
- }
-
- container restconf-state {
- config false;
- description
- "Contains RESTCONF protocol monitoring information.";
-
- container capabilities {
- description
- "Contains a list of protocol capability URIs.";
-
- leaf-list capability {
- type inet:uri;
- description
- "A RESTCONF protocol capability URI.";
- }
- }
-
- container streams {
- description
- "Container representing the notification event streams
- supported by the server.";
- reference
- "RFC 5277, Section 3.4, <streams> element.";
-
- list stream {
- key name;
- description
- "Each entry describes an event stream supported by
- the server.";
-
- leaf name {
- type string;
- description
- "The stream name.";
- reference
- "RFC 5277, Section 3.4, <name> element.";
- }
-
- leaf description {
- type string;
- description
- "Description of stream content.";
- reference
- "RFC 5277, Section 3.4, <description> element.";
- }
-
- leaf replay-support {
- type boolean;
- default false;
- description
- "Indicates if replay buffer is supported for this stream.
- If 'true', then the server MUST support the 'start-time'
- and 'stop-time' query parameters for this stream.";
- reference
- "RFC 5277, Section 3.4, <replaySupport> element.";
- }
-
- leaf replay-log-creation-time {
- when "../replay-support" {
- description
- "Only present if notification replay is supported.";
- }
- type yang:date-and-time;
- description
- "Indicates the time the replay log for this stream
- was created.";
- reference
- "RFC 5277, Section 3.4, <replayLogCreationTime>
- element.";
- }
-
- list access {
- key encoding;
- min-elements 1;
- description
- "The server will create an entry in this list for each
- encoding format that is supported for this stream.
- The media type 'text/event-stream' is expected
- for all event streams. This list identifies the
- subtypes supported for this stream.";
-
- leaf encoding {
- type string;
- description
- "This is the secondary encoding format within the
- 'text/event-stream' encoding used by all streams.
- The type 'xml' is supported for XML encoding.
- The type 'json' is supported for JSON encoding.";
- }
-
- leaf location {
- type inet:uri;
- mandatory true;
- description
- "Contains a URL that represents the entry point
- for establishing notification delivery via
- server-sent events.";
- }
- }
- }
- }
- }
-}
+++ /dev/null
-module ietf-restconf {
- namespace "urn:ietf:params:xml:ns:yang:ietf-restconf";
- prefix "restconf";
-
- import ietf-yang-types { prefix yang; }
- import ietf-inet-types { prefix inet; }
-
- organization
- "IETF NETCONF (Network Configuration) Working Group";
-
- contact
- "Editor: Andy Bierman
- <mailto:andy@yumaworks.com>
-
- Editor: Martin Bjorklund
- <mailto:mbj@tail-f.com>
-
- Editor: Kent Watsen
- <mailto:kwatsen@juniper.net>
-
- Editor: Rex Fernando
- <mailto:rex@cisco.com>";
-
- description
- "This module contains conceptual YANG specifications
- for the YANG Patch and error content that is used in
- RESTCONF protocol messages. A conceptual container
- representing the RESTCONF API nodes (media type
- application/yang.api).
-
- Note that the YANG definitions within this module do not
- represent configuration data of any kind.
- The YANG grouping statements provide a normative syntax
- for XML and JSON message encoding purposes.
- 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 XXXX; see
- the RFC itself for full legal notices.";
-
- // RFC Ed.: replace XXXX with actual RFC number and remove this
- // note.
-
- // RFC Ed.: remove this note
- // Note: extracted from draft-bierman-netconf-restconf-02.txt
-
- // RFC Ed.: update the date below with the date of RFC publication
- // and remove this note.
- revision 2013-10-19 {
- description
- "Initial revision.";
- reference
- "RFC XXXX: RESTCONF Protocol.";
- }
-
- typedef data-resource-identifier {
- type string {
- length "1 .. max";
- }
- description
- "Contains a Data Resource Identifier formatted string
- to identify a specific data node. The data node that
- uses this data type SHOULD define the document root
- for data resource identifiers. The default document
- root is the target datastore conceptual root node.
- Data resource identifiers are defined relative to
- this document root.";
- reference
- "RFC XXXX: [sec. 5.3.1.1 ABNF For Data Resource Identifiers]";
- }
-
- // this typedef is TBD; not currently used
- typedef datastore-identifier {
- type union {
- type enumeration {
- enum candidate {
- description
- "Identifies the NETCONF shared candidate datastore.";
- reference
- "RFC 6241, section 8.3";
- }
- enum running {
- description
- "Identifies the NETCONF running datastore.";
- reference
- "RFC 6241, section 5.1";
- }
- enum startup {
- description
- "Identifies the NETCONF startup datastore.";
- reference
- "RFC 6241, section 8.7";
- }
- }
- type string;
- }
- description
- "Contains a string to identify a specific datastore.
- The enumerated datastore identifier values are
- reserved for standard datastore names.";
- }
-
- typedef revision-identifier {
- type string {
- pattern '\d{4}-\d{2}-\d{2}';
- }
- description
- "Represents a specific date in YYYY-MM-DD format.
- TBD: make pattern more precise to exclude leading zeros.";
- }
-
- grouping yang-patch {
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of a
- YANG Patch edit request message.";
-
- container yang-patch {
- description
- "Represents a conceptual sequence of datastore edits,
- called a patch. Each patch is given a client-assigned
- patch identifier. Each edit MUST be applied
- in ascending order, and all edits MUST be applied.
- If any errors occur, then the target datastore MUST NOT
- be changed by the patch operation.
-
- A patch MUST be validated by the server to be a
- well-formed message before any of the patch edits
- are validated or attempted.
-
- YANG datastore validation (defined in RFC 6020, section
- 8.3.3) is performed after all edits have been
- individually validated.
-
- It is possible for a datastore constraint violation to occur
- due to any node in the datastore, including nodes not
- included in the edit list. Any validation errors MUST
- be reported in the reply message.";
-
- reference
- "RFC 6020, section 8.3.";
-
- leaf patch-id {
- type string;
- description
- "An arbitrary string provided by the client to identify
- the entire patch. This value SHOULD be present in any
- audit logging records generated by the server for the
- patch. Error messages returned by the server pertaining
- to this patch will be identified by this patch-id value.";
- }
-
- leaf comment {
- type string {
- length "0 .. 1024";
- }
- description
- "An arbitrary string provided by the client to describe
- the entire patch. This value SHOULD be present in any
- audit logging records generated by the server for the
- patch.";
- }
-
- list edit {
- key edit-id;
- ordered-by user;
-
- description
- "Represents one edit within the YANG Patch
- request message.";
- leaf edit-id {
- type string;
- description
- "Arbitrary string index for the edit.
- Error messages returned by the server pertaining
- to a specific edit will be identified by this
- value.";
- }
-
- leaf operation {
- type enumeration {
- enum create {
- description
- "The target data node is created using the
- supplied value, only if it does not already
- exist.";
- }
- enum delete {
- description
- "Delete the target node, only if the data resource
- currently exists, otherwise return an error.";
- }
- enum insert {
- description
- "Insert the supplied value into a user-ordered
- list or leaf-list entry. The target node must
- represent a new data resource.";
- }
- enum merge {
- description
- "The supplied value is merged with the target data
- node.";
- }
- enum move {
- description
- "Move the target node. Reorder a user-ordered
- list or leaf-list. The target node must represent
- an existing data resource.";
- }
- enum replace {
- description
- "The supplied value is used to replace the target
- data node.";
- }
- enum remove {
- description
- "Delete the target node if it currently exists.";
- }
- }
- mandatory true;
- description
- "The datastore operation requested for the associated
- edit entry";
- }
-
- leaf target {
- type data-resource-identifier;
- mandatory true;
- description
- "Identifies the target data resource for the edit
- operation.";
- }
-
- leaf point {
- when "(../operation = 'insert' or " +
- "../operation = 'move') and " +
- "(../where = 'before' or ../where = 'after')" {
- description
- "Point leaf only applies for insert or move
- operations, before or after an existing entry.";
- }
- type data-resource-identifier;
- description
- "The absolute URL path for the data node that is being
- used as the insertion point or move point for the
- target of this edit entry.";
- }
-
- leaf where {
- when "../operation = 'insert' or ../operation = 'move'" {
- description
- "Where leaf only applies for insert or move
- operations.";
- }
- type enumeration {
- enum before {
- description
- "Insert or move a data node before the data resource
- identified by the 'point' parameter.";
- }
- enum after {
- description
- "Insert or move a data node after the data resource
- identified by the 'point' parameter.";
- }
- enum first {
- description
- "Insert or move a data node so it becomes ordered
- as the first entry.";
- }
- enum last {
- description
- "Insert or move a data node so it becomes ordered
- as the last entry.";
- }
-
- }
- default last;
- description
- "Identifies where a data resource will be inserted or
- moved. YANG only allows these operations for
- list and leaf-list data nodes that are ordered-by
- user.";
- }
-
- anyxml value {
- when "(../operation = 'create' or " +
- "../operation = 'merge' " +
- "or ../operation = 'replace' or " +
- "../operation = 'insert')" {
- description
- "Value node only used for create, merge,
- replace, and insert operations";
- }
- description
- "Value used for this edit operation.";
- }
- }
- }
-
- } // grouping yang-patch
-
-
- grouping yang-patch-status {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of
- YANG Patch status response message.";
-
- container yang-patch-status {
- description
- "A container representing the response message
- sent by the server after a YANG Patch edit
- request message has been processed.";
-
- leaf patch-id {
- type string;
- description
- "The patch-id value used in the request";
- }
-
- choice global-status {
- description
- "Report global errors or complete success.
- If there is no case selected then errors
- are reported in the edit-status container.";
-
- case global-errors {
- uses errors;
- description
- "This container will be present if global
- errors unrelated to a specific edit occurred.";
- }
- leaf ok {
- type empty;
- description
- "This leaf will be present if the request succeeded
- and there are no errors reported in the edit-status
- container.";
- }
- }
-
- container edit-status {
- description
- "This container will be present if there are
- edit-specific status responses to report.";
-
- list edit {
- key edit-id;
-
- description
- "Represents a list of status responses,
- corresponding to edits in the YANG Patch
- request message. If an edit entry was
- skipped or not reached by the server,
- then this list will not contain a corresponding
- entry for that edit.";
-
- leaf edit-id {
- type string;
- description
- "Response status is for the edit list entry
- with this edit-id value.";
- }
- choice edit-status-choice {
- description
- "A choice between different types of status
- responses for each edit entry.";
- leaf ok {
- type empty;
- description
- "This edit entry was invoked without any
- errors detected by the server associated
- with this edit.";
- }
- leaf location {
- type inet:uri;
- description
- "Contains the Location header value that would be
- returned if this edit causes a new resource to be
- created. If the edit identified by the same edit-id
- value was successfully invoked and a new resource
- was created, then this field will be returned
- instead of 'ok'.";
- }
- case errors {
- uses errors;
- description
- "The server detected errors associated with the
- edit identified by the same edit-id value.";
- }
- }
- }
- }
- }
- } // grouping yang-patch-status
-
-
- grouping errors {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of a
- YANG Patch errors report within a response message.";
-
- container errors {
- config false; // needed so list error does not need a key
- description
- "Represents an error report returned by the server if
- a request results in an error.";
-
- list error {
- description
- "An entry containing information about one
- specific error that occurred while processing
- a RESTCONF request.";
- reference "RFC 6241, Section 4.3";
-
- leaf error-type {
- type enumeration {
- enum transport {
- description "The transport layer";
- }
- enum rpc {
- description "The rpc or notification layer";
- }
- enum protocol {
- description "The protocol operation layer";
- }
- enum application {
- description "The server application layer";
- }
- }
- mandatory true;
- description
- "The protocol layer where the error occurred.";
- }
-
- leaf error-tag {
- type string;
- mandatory true;
- description
- "The enumerated error tag.";
- }
-
- leaf error-app-tag {
- type string;
- description
- "The application-specific error tag.";
- }
-
- leaf error-path {
- type data-resource-identifier;
- description
- "The target data resource identifier associated
- with the error, if any.";
- }
- leaf error-message {
- type string;
- description
- "A message describing the error.";
- }
-
- container error-info {
- description
- "A container allowing additional information
- to be included in the error report.";
- // arbitrary anyxml content here
- }
- }
- }
- } // grouping errors
-
-
- grouping restconf {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of
- the RESTCONF API resource.";
-
- container restconf {
- description
- "Conceptual container representing the
- application/yang.api resource type.";
-
- container config {
- description
- "Container representing the application/yang.datastore
- resource type. Represents the conceptual root of the
- unified configuration datastore containing YANG data
- nodes. The child nodes of this container are
- configuration data resources (application/yang.data)
- defined as top-level YANG data nodes from the modules
- advertised by the server in /restconf/modules.";
- }
-
- container operational {
- description
- "Container representing the application/yang.datastore
- resource type. Represents the conceptual root of the
- operational data supported by the server. The child
- nodes of this container are operational data resources
- (application/yang.data) defined as top-level
- YANG data nodes from the modules advertised by
- the server in /restconf/modules.";
- }
-
- container modules {
- description
- "Contains a list of module description entries.
- These modules are currently loaded into the server.";
-
- list module {
- key "name revision";
- description
- "Each entry represents one module currently
- supported by the server.";
-
- leaf name {
- type yang:yang-identifier;
- description "The YANG module name.";
- }
- leaf revision {
- type union {
- type revision-identifier;
- type string { length 0; }
- }
- description
- "The YANG module revision date. An empty string is
- used if no revision statement is present in the
- YANG module.";
- }
- leaf namespace {
- type inet:uri;
- mandatory true;
- description
- "The XML namespace identifier for this module.";
- }
- leaf-list feature {
- type yang:yang-identifier;
- description
- "List of YANG feature names from this module that are
- supported by the server.";
- }
- leaf-list deviation {
- type yang:yang-identifier;
- description
- "List of YANG deviation module names used by this
- server to modify the conformance of the module
- associated with this entry.";
- }
- }
- }
-
- container operations {
- description
- "Container for all operation resources
- (application/yang.operation),
-
- Each resource is represented as an empty leaf with the
- name of the RPC operation from the YANG rpc statement.
-
- E.g.;
-
- POST /restconf/operations/show-log-errors
-
- leaf show-log-errors {
- type empty;
- }
- ";
- }
-
- container streams {
- description
- "Container representing the notification event streams
- supported by the server.";
- reference
- "RFC 5277, Section 3.4, <streams> element.";
-
- list stream {
- key name;
- description
- "Each entry describes an event stream supported by
- the server.";
-
- leaf name {
- type string;
- description "The stream name";
- reference "RFC 5277, Section 3.4, <name> element.";
- }
-
- leaf description {
- type string;
- description "Description of stream content";
- reference
- "RFC 5277, Section 3.4, <description> element.";
- }
-
- leaf replay-support {
- type boolean;
- description
- "Indicates if replay buffer supported for this stream";
- reference
- "RFC 5277, Section 3.4, <replaySupport> element.";
- }
-
- leaf replay-log-creation-time {
- type yang:date-and-time;
- description
- "Indicates the time the replay log for this stream
- was created.";
- reference
- "RFC 5277, Section 3.4, <replayLogCreationTime>
- element.";
- }
-
- leaf events {
- type empty;
- description
- "Represents the entry point for establishing
- notification delivery via server sent events.";
- }
- }
- }
-
- leaf version {
- type enumeration {
- enum "1.0" {
- description
- "Version 1.0 of the RESTCONF protocol.";
- }
- }
- config false;
- description
- "Contains the RESTCONF protocol version.";
- }
- }
- } // grouping restconf
-
-
- grouping notification {
- description
- "Contains the notification message wrapper definition.";
-
- container notification {
- description
- "RESTCONF notification message wrapper.";
- leaf event-time {
- type yang:date-and-time;
- mandatory true;
- description
- "The time the event was generated by the
- event source.";
- reference
- "RFC 5277, section 4, <eventTime> element.";
- }
-
- /* The YANG-specific notification container is encoded
- * after the 'event-time' element. The format
- * corresponds to the notificationContent element
- * in RFC 5277, section 4. For example:
- *
- * module example-one {
- * ...
- * notification event1 { ... }
- *
- * }
- *
- * Encoded as element 'event1' in the namespace
- * for module 'example-one'.
- */
- }
- } // grouping notification
-
- }
\ No newline at end of file
+++ /dev/null
-module ietf-yang-library {
- namespace "urn:ietf:params:xml:ns:yang:ietf-yang-library";
- prefix "yanglib";
- import ietf-yang-types {
- prefix yang;
- }
- import ietf-inet-types {
- prefix inet;
- }
- organization
- "IETF NETCONF (Network Configuration) Working Group";
- contact
- "WG Web: <https://datatracker.ietf.org/wg/netconf/>
- WG List: <mailto:netconf@ietf.org>
- WG Chair: Mehmet Ersue
- <mailto:mehmet.ersue@nsn.com>
- WG Chair: Mahesh Jethanandani
- <mailto:mjethanandani@gmail.com>
- Editor: Andy Bierman
- <mailto:andy@yumaworks.com>
- Editor: Martin Bjorklund
- <mailto:mbj@tail-f.com>
- Editor: Kent Watsen
- <mailto:kwatsen@juniper.net>";
- description
- "This module contains monitoring information about the YANG
- modules and submodules that are used within a YANG-based
- server.
- Copyright (c) 2016 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 7895; see
- the RFC itself for full legal notices.";
- revision 2016-06-21 {
- description
- "Initial revision.";
- reference
- "RFC 7895: YANG Module Library.";
- }
- /*
- * Typedefs
- */
- typedef revision-identifier {
- type string {
- pattern '\d{4}-\d{2}-\d{2}';
- }
- description
- "Represents a specific date in YYYY-MM-DD format.";
- }
- /*
- * Groupings
- */
- grouping module-list {
- description
- "The module data structure is represented as a grouping
- so it can be reused in configuration or another monitoring
- data structure.";
- grouping common-leafs {
- description
- "Common parameters for YANG modules and submodules.";
- leaf name {
- type yang:yang-identifier;
- description
- "The YANG module or submodule name.";
- }
- leaf revision {
- type union {
- type revision-identifier;
- type string { length 0; }
- }
- description
- "The YANG module or submodule revision date.
- A zero-length string is used if no revision statement
- is present in the YANG module or submodule.";
- }
- }
- grouping schema-leaf {
- description
- "Common schema leaf parameter for modules and submodules.";
- leaf schema {
- type inet:uri;
- description
- "Contains a URL that represents the YANG schema
- resource for this module or submodule.
- This leaf will only be present if there is a URL
- available for retrieval of the schema for this entry.";
- }
- }
- list module {
- key "name revision";
- description
- "Each entry represents one revision of one module
- currently supported by the server.";
- uses common-leafs;
- uses schema-leaf;
- leaf namespace {
- type inet:uri;
- mandatory true;
- description
- "The XML namespace identifier for this module.";
- }
- leaf-list feature {
- type yang:yang-identifier;
- description
- "List of YANG feature names from this module that are
- supported by the server, regardless of whether they are
- defined in the module or any included submodule.";
- }
- list deviation {
- key "name revision";
- description
- "List of YANG deviation module names and revisions
- used by this server to modify the conformance of
- the module associated with this entry. Note that
- the same module can be used for deviations for
- multiple modules, so the same entry MAY appear
- within multiple 'module' entries.
- The deviation module MUST be present in the 'module'
- list, with the same name and revision values.
- The 'conformance-type' value will be 'implement' for
- the deviation module.";
- uses common-leafs;
- }
- leaf conformance-type {
- type enumeration {
- enum implement {
- description
- "Indicates that the server implements one or more
- protocol-accessible objects defined in the YANG module
- identified in this entry. This includes deviation
- statements defined in the module.
- For YANG version 1.1 modules, there is at most one
- module entry with conformance type 'implement' for a
- particular module name, since YANG 1.1 requires that,
- at most, one revision of a module is implemented.
- For YANG version 1 modules, there SHOULD NOT be more
- than one module entry for a particular module name.";
- }
- enum import {
- description
- "Indicates that the server imports reusable definitions
- from the specified revision of the module but does
- not implement any protocol-accessible objects from
- this revision.
- Multiple module entries for the same module name MAY
- exist. This can occur if multiple modules import the
- same module but specify different revision dates in
- the import statements.";
- }
- }
- mandatory true;
- description
- "Indicates the type of conformance the server is claiming
- for the YANG module identified by this entry.";
- }
- list submodule {
- key "name revision";
- description
- "Each entry represents one submodule within the
- parent module.";
- uses common-leafs;
- uses schema-leaf;
- }
- }
- }
- /*
- * Operational state data nodes
- */
- container modules-state {
- config false;
- description
- "Contains YANG module monitoring information.";
- leaf module-set-id {
- type string;
- mandatory true;
- description
- "Contains a server-specific identifier representing
- the current set of modules and submodules. The
- server MUST change the value of this leaf if the
- information represented by the 'module' list instances
- has changed.";
- }
- uses module-list;
- }
- /*
- * Notifications
- */
- notification yang-library-change {
- description
- "Generated when the set of modules and submodules supported
- by the server has changed.";
- leaf module-set-id {
- type leafref {
- path "/yanglib:modules-state/yanglib:module-set-id";
- }
- mandatory true;
- description
- "Contains the module-set-id value representing the
- set of modules and submodules supported at the server at
- the time the notification is generated.";
- }
- }
-}
+++ /dev/null
- 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)";
- }
-
- 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 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";
- }
-
- }
+++ /dev/null
-module module1-behind-mount-point {
- namespace "module:1:behind:mount:point";
- prefix "mod1bemopo";
- revision "2014-02-03";
-
- rpc rpc-behind-module1 {
- }
-
-
-}
\ No newline at end of file
+++ /dev/null
-module module2-behind-mount-point {
- namespace "module:2:behind:mount:point";
- prefix "mod2bemopo";
- revision "2014-02-04";
-
- rpc rpc-behind-module2 {
- }
-
-}
\ No newline at end of file
+++ /dev/null
-module module1 {
- namespace "module:1";
- prefix "mod1";
- revision "2014-01-01";
-
- rpc dummy-rpc1-module1 {
- }
-
- rpc dummy-rpc2-module1 {
- }
-
-}
\ No newline at end of file
+++ /dev/null
-module module2 {
- namespace "module:2";
- prefix "mod2";
- revision "2014-01-02";
-
- rpc dummy-rpc1-module2 {
- }
-
- rpc dummy-rpc2-module2 {
- }
-}
\ No newline at end of file
+++ /dev/null
-module module3 {
- namespace "module:3";
- prefix "mod3";
- revision "2014-01-03";
-}
\ No newline at end of file
+++ /dev/null
-module mount-point-1 {
- namespace "mount:point:1";
- prefix "point1";
- revision "2016-01-01";
-
- container cont {
- }
-
- list listA {
- }
-}
\ No newline at end of file
+++ /dev/null
-module mount-point-1 {
- namespace "mount:point:1";
- prefix "point1";
- revision "2016-01-01";
-
- container cont {
- }
-
- list listA {
- }
-}
\ No newline at end of file
+++ /dev/null
-module mount-point-2 {
- namespace "mount:point:2";
- prefix "point2";
- revision "2016-01-01";
-
- container cont {
- }
-}
\ No newline at end of file
+++ /dev/null
-module nested-module {
- namespace "urn:nested:module";
- prefix "nested";
- revision "2014-06-03";
-
- container depth1-cont {
- list depth2-cont1 {
- container depth3-cont1 {
- container depth4-cont1 {
- leaf depth5-leaf1 {
- type string;
- }
- }
-
- leaf depth4-leaf1 {
- type string;
- }
- }
-
- leaf depth3-leaf1 {
- type string;
- }
- }
-
- /* list depth2-list2 was added to test keyed list */
- list depth2-list2 {
- key "depth3-lf1-key depth3-lf2-key";
- leaf depth3-lf1-key {
- type string;
- }
- leaf depth3-lf2-key {
- type string;
- }
- leaf depth3-lf3 {
- type string;
- }
- }
-
- leaf-list depth2-lfLst1 {
- type string;
- }
-
- container depth2-cont2 {
- container depth3-cont2 {
- container depth4-cont2 {
- leaf depth5-leaf2 {
- type string;
- }
- }
-
- leaf depth4-leaf2 {
- type string;
- }
- }
-
- leaf depth3-leaf2 {
- type string;
- }
- }
-
- leaf depth2-leaf1 {
- type string;
- }
- }
-
- notification notifi{
- description "Notifi";
- }
-}
+++ /dev/null
- 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)";
- }
-
- }
+++ /dev/null
- 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)";
- }
-
- 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 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";
- }
-
- }
+++ /dev/null
-module mount-point-1 {
- namespace "mount:point:1";
- prefix "point1";
- revision "2016-01-01";
-
- container cont {
- }
-
- list listA {
- }
-}
\ No newline at end of file
+++ /dev/null
-module restconf-module-with-illegal-container-modules {
- namespace "urn:ietf:params:xml:ns:yang:ietf-restconf";
- prefix "restconf";
-
- import ietf-yang-types { prefix yang; }
- import ietf-inet-types { prefix inet; }
-
- organization
- "IETF NETCONF (Network Configuration) Working Group";
-
- contact
- "Editor: Andy Bierman
- <mailto:andy@yumaworks.com>
-
- Editor: Martin Bjorklund
- <mailto:mbj@tail-f.com>
-
- Editor: Kent Watsen
- <mailto:kwatsen@juniper.net>
-
- Editor: Rex Fernando
- <mailto:rex@cisco.com>";
-
- description
- "This module contains conceptual YANG specifications
- for the YANG Patch and error content that is used in
- RESTCONF protocol messages. A conceptual container
- representing the RESTCONF API nodes (media type
- application/yang.api).
-
- Note that the YANG definitions within this module do not
- represent configuration data of any kind.
- The YANG grouping statements provide a normative syntax
- for XML and JSON message encoding purposes.
- 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 XXXX; see
- the RFC itself for full legal notices.";
-
- // RFC Ed.: replace XXXX with actual RFC number and remove this
- // note.
-
- // RFC Ed.: remove this note
- // Note: extracted from draft-bierman-netconf-restconf-02.txt
-
- // RFC Ed.: update the date below with the date of RFC publication
- // and remove this note.
- revision 2013-10-19 {
- description
- "Initial revision.";
- reference
- "RFC XXXX: RESTCONF Protocol.";
- }
-
- typedef data-resource-identifier {
- type string {
- length "1 .. max";
- }
- description
- "Contains a Data Resource Identifier formatted string
- to identify a specific data node. The data node that
- uses this data type SHOULD define the document root
- for data resource identifiers. The default document
- root is the target datastore conceptual root node.
- Data resource identifiers are defined relative to
- this document root.";
- reference
- "RFC XXXX: [sec. 5.3.1.1 ABNF For Data Resource Identifiers]";
- }
-
- // this typedef is TBD; not currently used
- typedef datastore-identifier {
- type union {
- type enumeration {
- enum candidate {
- description
- "Identifies the NETCONF shared candidate datastore.";
- reference
- "RFC 6241, section 8.3";
- }
- enum running {
- description
- "Identifies the NETCONF running datastore.";
- reference
- "RFC 6241, section 5.1";
- }
- enum startup {
- description
- "Identifies the NETCONF startup datastore.";
- reference
- "RFC 6241, section 8.7";
- }
- }
- type string;
- }
- description
- "Contains a string to identify a specific datastore.
- The enumerated datastore identifier values are
- reserved for standard datastore names.";
- }
-
- typedef revision-identifier {
- type string {
- pattern '\d{4}-\d{2}-\d{2}';
- }
- description
- "Represents a specific date in YYYY-MM-DD format.
- TBD: make pattern more precise to exclude leading zeros.";
- }
-
- grouping yang-patch {
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of a
- YANG Patch edit request message.";
-
- container yang-patch {
- description
- "Represents a conceptual sequence of datastore edits,
- called a patch. Each patch is given a client-assigned
- patch identifier. Each edit MUST be applied
- in ascending order, and all edits MUST be applied.
- If any errors occur, then the target datastore MUST NOT
- be changed by the patch operation.
-
- A patch MUST be validated by the server to be a
- well-formed message before any of the patch edits
- are validated or attempted.
-
- YANG datastore validation (defined in RFC 6020, section
- 8.3.3) is performed after all edits have been
- individually validated.
-
- It is possible for a datastore constraint violation to occur
- due to any node in the datastore, including nodes not
- included in the edit list. Any validation errors MUST
- be reported in the reply message.";
-
- reference
- "RFC 6020, section 8.3.";
-
- leaf patch-id {
- type string;
- description
- "An arbitrary string provided by the client to identify
- the entire patch. This value SHOULD be present in any
- audit logging records generated by the server for the
- patch. Error messages returned by the server pertaining
- to this patch will be identified by this patch-id value.";
- }
-
- leaf comment {
- type string {
- length "0 .. 1024";
- }
- description
- "An arbitrary string provided by the client to describe
- the entire patch. This value SHOULD be present in any
- audit logging records generated by the server for the
- patch.";
- }
-
- list edit {
- key edit-id;
- ordered-by user;
-
- description
- "Represents one edit within the YANG Patch
- request message.";
- leaf edit-id {
- type string;
- description
- "Arbitrary string index for the edit.
- Error messages returned by the server pertaining
- to a specific edit will be identified by this
- value.";
- }
-
- leaf operation {
- type enumeration {
- enum create {
- description
- "The target data node is created using the
- supplied value, only if it does not already
- exist.";
- }
- enum delete {
- description
- "Delete the target node, only if the data resource
- currently exists, otherwise return an error.";
- }
- enum insert {
- description
- "Insert the supplied value into a user-ordered
- list or leaf-list entry. The target node must
- represent a new data resource.";
- }
- enum merge {
- description
- "The supplied value is merged with the target data
- node.";
- }
- enum move {
- description
- "Move the target node. Reorder a user-ordered
- list or leaf-list. The target node must represent
- an existing data resource.";
- }
- enum replace {
- description
- "The supplied value is used to replace the target
- data node.";
- }
- enum remove {
- description
- "Delete the target node if it currently exists.";
- }
- }
- mandatory true;
- description
- "The datastore operation requested for the associated
- edit entry";
- }
-
- leaf target {
- type data-resource-identifier;
- mandatory true;
- description
- "Identifies the target data resource for the edit
- operation.";
- }
-
- leaf point {
- when "(../operation = 'insert' or " +
- "../operation = 'move') and " +
- "(../where = 'before' or ../where = 'after')" {
- description
- "Point leaf only applies for insert or move
- operations, before or after an existing entry.";
- }
- type data-resource-identifier;
- description
- "The absolute URL path for the data node that is being
- used as the insertion point or move point for the
- target of this edit entry.";
- }
-
- leaf where {
- when "../operation = 'insert' or ../operation = 'move'" {
- description
- "Where leaf only applies for insert or move
- operations.";
- }
- type enumeration {
- enum before {
- description
- "Insert or move a data node before the data resource
- identified by the 'point' parameter.";
- }
- enum after {
- description
- "Insert or move a data node after the data resource
- identified by the 'point' parameter.";
- }
- enum first {
- description
- "Insert or move a data node so it becomes ordered
- as the first entry.";
- }
- enum last {
- description
- "Insert or move a data node so it becomes ordered
- as the last entry.";
- }
-
- }
- default last;
- description
- "Identifies where a data resource will be inserted or
- moved. YANG only allows these operations for
- list and leaf-list data nodes that are ordered-by
- user.";
- }
-
- anyxml value {
- when "(../operation = 'create' or " +
- "../operation = 'merge' " +
- "or ../operation = 'replace' or " +
- "../operation = 'insert')" {
- description
- "Value node only used for create, merge,
- replace, and insert operations";
- }
- description
- "Value used for this edit operation.";
- }
- }
- }
-
- } // grouping yang-patch
-
-
- grouping yang-patch-status {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of
- YANG Patch status response message.";
-
- container yang-patch-status {
- description
- "A container representing the response message
- sent by the server after a YANG Patch edit
- request message has been processed.";
-
- leaf patch-id {
- type string;
- description
- "The patch-id value used in the request";
- }
-
- choice global-status {
- description
- "Report global errors or complete success.
- If there is no case selected then errors
- are reported in the edit-status container.";
-
- case global-errors {
- uses errors;
- description
- "This container will be present if global
- errors unrelated to a specific edit occurred.";
- }
- leaf ok {
- type empty;
- description
- "This leaf will be present if the request succeeded
- and there are no errors reported in the edit-status
- container.";
- }
- }
-
- container edit-status {
- description
- "This container will be present if there are
- edit-specific status responses to report.";
-
- list edit {
- key edit-id;
-
- description
- "Represents a list of status responses,
- corresponding to edits in the YANG Patch
- request message. If an edit entry was
- skipped or not reached by the server,
- then this list will not contain a corresponding
- entry for that edit.";
-
- leaf edit-id {
- type string;
- description
- "Response status is for the edit list entry
- with this edit-id value.";
- }
- choice edit-status-choice {
- description
- "A choice between different types of status
- responses for each edit entry.";
- leaf ok {
- type empty;
- description
- "This edit entry was invoked without any
- errors detected by the server associated
- with this edit.";
- }
- leaf location {
- type inet:uri;
- description
- "Contains the Location header value that would be
- returned if this edit causes a new resource to be
- created. If the edit identified by the same edit-id
- value was successfully invoked and a new resource
- was created, then this field will be returned
- instead of 'ok'.";
- }
- case errors {
- uses errors;
- description
- "The server detected errors associated with the
- edit identified by the same edit-id value.";
- }
- }
- }
- }
- }
- } // grouping yang-patch-status
-
-
- grouping errors {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of a
- YANG Patch errors report within a response message.";
-
- container errors {
- config false; // needed so list error does not need a key
- description
- "Represents an error report returned by the server if
- a request results in an error.";
-
- list error {
- description
- "An entry containing information about one
- specific error that occurred while processing
- a RESTCONF request.";
- reference "RFC 6241, Section 4.3";
-
- leaf error-type {
- type enumeration {
- enum transport {
- description "The transport layer";
- }
- enum rpc {
- description "The rpc or notification layer";
- }
- enum protocol {
- description "The protocol operation layer";
- }
- enum application {
- description "The server application layer";
- }
- }
- mandatory true;
- description
- "The protocol layer where the error occurred.";
- }
-
- leaf error-tag {
- type string;
- mandatory true;
- description
- "The enumerated error tag.";
- }
-
- leaf error-app-tag {
- type string;
- description
- "The application-specific error tag.";
- }
-
- leaf error-path {
- type data-resource-identifier;
- description
- "The target data resource identifier associated
- with the error, if any.";
- }
- leaf error-message {
- type string;
- description
- "A message describing the error.";
- }
-
- container error-info {
- description
- "A container allowing additional information
- to be included in the error report.";
- // arbitrary anyxml content here
- }
- }
- }
- } // grouping errors
-
-
- grouping restconf {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of
- the RESTCONF API resource.";
-
- container restconf {
- description
- "Conceptual container representing the
- application/yang.api resource type.";
-
- container config {
- description
- "Container representing the application/yang.datastore
- resource type. Represents the conceptual root of the
- unified configuration datastore containing YANG data
- nodes. The child nodes of this container are
- configuration data resources (application/yang.data)
- defined as top-level YANG data nodes from the modules
- advertised by the server in /restconf/modules.";
- }
-
- container operational {
- description
- "Container representing the application/yang.datastore
- resource type. Represents the conceptual root of the
- operational data supported by the server. The child
- nodes of this container are operational data resources
- (application/yang.data) defined as top-level
- YANG data nodes from the modules advertised by
- the server in /restconf/modules.";
- }
-
- /** changed from container modules to list modules for testing purposes **/
- list modules {
- description
- "Contains a list of module description entries.
- These modules are currently loaded into the server.";
-
- list module {
- key "name revision";
- description
- "Each entry represents one module currently
- supported by the server.";
-
- leaf name {
- type yang:yang-identifier;
- description "The YANG module name.";
- }
- leaf revision {
- type union {
- type revision-identifier;
- type string { length 0; }
- }
- description
- "The YANG module revision date. An empty string is
- used if no revision statement is present in the
- YANG module.";
- }
- leaf namespace {
- type inet:uri;
- mandatory true;
- description
- "The XML namespace identifier for this module.";
- }
- leaf-list feature {
- type yang:yang-identifier;
- description
- "List of YANG feature names from this module that are
- supported by the server.";
- }
- leaf-list deviation {
- type yang:yang-identifier;
- description
- "List of YANG deviation module names used by this
- server to modify the conformance of the module
- associated with this entry.";
- }
- }
- }
-
- container operations {
- description
- "Container for all operation resources
- (application/yang.operation),
-
- Each resource is represented as an empty leaf with the
- name of the RPC operation from the YANG rpc statement.
-
- E.g.;
-
- POST /restconf/operations/show-log-errors
-
- leaf show-log-errors {
- type empty;
- }
- ";
- }
-
- container streams {
- description
- "Container representing the notification event streams
- supported by the server.";
- reference
- "RFC 5277, Section 3.4, <streams> element.";
-
- list stream {
- key name;
- description
- "Each entry describes an event stream supported by
- the server.";
-
- leaf name {
- type string;
- description "The stream name";
- reference "RFC 5277, Section 3.4, <name> element.";
- }
-
- leaf description {
- type string;
- description "Description of stream content";
- reference
- "RFC 5277, Section 3.4, <description> element.";
- }
-
- leaf replay-support {
- type boolean;
- description
- "Indicates if replay buffer supported for this stream";
- reference
- "RFC 5277, Section 3.4, <replaySupport> element.";
- }
-
- leaf replay-log-creation-time {
- type yang:date-and-time;
- description
- "Indicates the time the replay log for this stream
- was created.";
- reference
- "RFC 5277, Section 3.4, <replayLogCreationTime>
- element.";
- }
-
- leaf events {
- type empty;
- description
- "Represents the entry point for establishing
- notification delivery via server sent events.";
- }
- }
- }
-
- leaf version {
- type enumeration {
- enum "1.0" {
- description
- "Version 1.0 of the RESTCONF protocol.";
- }
- }
- config false;
- description
- "Contains the RESTCONF protocol version.";
- }
- }
- } // grouping restconf
-
-
- grouping notification {
- description
- "Contains the notification message wrapper definition.";
-
- container notification {
- description
- "RESTCONF notification message wrapper.";
- leaf event-time {
- type yang:date-and-time;
- mandatory true;
- description
- "The time the event was generated by the
- event source.";
- reference
- "RFC 5277, section 4, <eventTime> element.";
- }
-
- /* The YANG-specific notification container is encoded
- * after the 'event-time' element. The format
- * corresponds to the notificationContent element
- * in RFC 5277, section 4. For example:
- *
- * module example-one {
- * ...
- * notification event1 { ... }
- *
- * }
- *
- * Encoded as element 'event1' in the namespace
- * for module 'example-one'.
- */
- }
- } // grouping notification
-
- }
\ No newline at end of file
+++ /dev/null
-module restconf-module-with-illegal-list-module {
- namespace "urn:ietf:params:xml:ns:yang:ietf-restconf";
- prefix "restconf";
-
- import ietf-yang-types { prefix yang; }
- import ietf-inet-types { prefix inet; }
-
- organization
- "IETF NETCONF (Network Configuration) Working Group";
-
- contact
- "Editor: Andy Bierman
- <mailto:andy@yumaworks.com>
-
- Editor: Martin Bjorklund
- <mailto:mbj@tail-f.com>
-
- Editor: Kent Watsen
- <mailto:kwatsen@juniper.net>
-
- Editor: Rex Fernando
- <mailto:rex@cisco.com>";
-
- description
- "This module contains conceptual YANG specifications
- for the YANG Patch and error content that is used in
- RESTCONF protocol messages. A conceptual container
- representing the RESTCONF API nodes (media type
- application/yang.api).
-
- Note that the YANG definitions within this module do not
- represent configuration data of any kind.
- The YANG grouping statements provide a normative syntax
- for XML and JSON message encoding purposes.
- 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 XXXX; see
- the RFC itself for full legal notices.";
-
- // RFC Ed.: replace XXXX with actual RFC number and remove this
- // note.
-
- // RFC Ed.: remove this note
- // Note: extracted from draft-bierman-netconf-restconf-02.txt
-
- // RFC Ed.: update the date below with the date of RFC publication
- // and remove this note.
- revision 2013-10-19 {
- description
- "Initial revision.";
- reference
- "RFC XXXX: RESTCONF Protocol.";
- }
-
- typedef data-resource-identifier {
- type string {
- length "1 .. max";
- }
- description
- "Contains a Data Resource Identifier formatted string
- to identify a specific data node. The data node that
- uses this data type SHOULD define the document root
- for data resource identifiers. The default document
- root is the target datastore conceptual root node.
- Data resource identifiers are defined relative to
- this document root.";
- reference
- "RFC XXXX: [sec. 5.3.1.1 ABNF For Data Resource Identifiers]";
- }
-
- // this typedef is TBD; not currently used
- typedef datastore-identifier {
- type union {
- type enumeration {
- enum candidate {
- description
- "Identifies the NETCONF shared candidate datastore.";
- reference
- "RFC 6241, section 8.3";
- }
- enum running {
- description
- "Identifies the NETCONF running datastore.";
- reference
- "RFC 6241, section 5.1";
- }
- enum startup {
- description
- "Identifies the NETCONF startup datastore.";
- reference
- "RFC 6241, section 8.7";
- }
- }
- type string;
- }
- description
- "Contains a string to identify a specific datastore.
- The enumerated datastore identifier values are
- reserved for standard datastore names.";
- }
-
- typedef revision-identifier {
- type string {
- pattern '\d{4}-\d{2}-\d{2}';
- }
- description
- "Represents a specific date in YYYY-MM-DD format.
- TBD: make pattern more precise to exclude leading zeros.";
- }
-
- grouping yang-patch {
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of a
- YANG Patch edit request message.";
-
- container yang-patch {
- description
- "Represents a conceptual sequence of datastore edits,
- called a patch. Each patch is given a client-assigned
- patch identifier. Each edit MUST be applied
- in ascending order, and all edits MUST be applied.
- If any errors occur, then the target datastore MUST NOT
- be changed by the patch operation.
-
- A patch MUST be validated by the server to be a
- well-formed message before any of the patch edits
- are validated or attempted.
-
- YANG datastore validation (defined in RFC 6020, section
- 8.3.3) is performed after all edits have been
- individually validated.
-
- It is possible for a datastore constraint violation to occur
- due to any node in the datastore, including nodes not
- included in the edit list. Any validation errors MUST
- be reported in the reply message.";
-
- reference
- "RFC 6020, section 8.3.";
-
- leaf patch-id {
- type string;
- description
- "An arbitrary string provided by the client to identify
- the entire patch. This value SHOULD be present in any
- audit logging records generated by the server for the
- patch. Error messages returned by the server pertaining
- to this patch will be identified by this patch-id value.";
- }
-
- leaf comment {
- type string {
- length "0 .. 1024";
- }
- description
- "An arbitrary string provided by the client to describe
- the entire patch. This value SHOULD be present in any
- audit logging records generated by the server for the
- patch.";
- }
-
- list edit {
- key edit-id;
- ordered-by user;
-
- description
- "Represents one edit within the YANG Patch
- request message.";
- leaf edit-id {
- type string;
- description
- "Arbitrary string index for the edit.
- Error messages returned by the server pertaining
- to a specific edit will be identified by this
- value.";
- }
-
- leaf operation {
- type enumeration {
- enum create {
- description
- "The target data node is created using the
- supplied value, only if it does not already
- exist.";
- }
- enum delete {
- description
- "Delete the target node, only if the data resource
- currently exists, otherwise return an error.";
- }
- enum insert {
- description
- "Insert the supplied value into a user-ordered
- list or leaf-list entry. The target node must
- represent a new data resource.";
- }
- enum merge {
- description
- "The supplied value is merged with the target data
- node.";
- }
- enum move {
- description
- "Move the target node. Reorder a user-ordered
- list or leaf-list. The target node must represent
- an existing data resource.";
- }
- enum replace {
- description
- "The supplied value is used to replace the target
- data node.";
- }
- enum remove {
- description
- "Delete the target node if it currently exists.";
- }
- }
- mandatory true;
- description
- "The datastore operation requested for the associated
- edit entry";
- }
-
- leaf target {
- type data-resource-identifier;
- mandatory true;
- description
- "Identifies the target data resource for the edit
- operation.";
- }
-
- leaf point {
- when "(../operation = 'insert' or " +
- "../operation = 'move') and " +
- "(../where = 'before' or ../where = 'after')" {
- description
- "Point leaf only applies for insert or move
- operations, before or after an existing entry.";
- }
- type data-resource-identifier;
- description
- "The absolute URL path for the data node that is being
- used as the insertion point or move point for the
- target of this edit entry.";
- }
-
- leaf where {
- when "../operation = 'insert' or ../operation = 'move'" {
- description
- "Where leaf only applies for insert or move
- operations.";
- }
- type enumeration {
- enum before {
- description
- "Insert or move a data node before the data resource
- identified by the 'point' parameter.";
- }
- enum after {
- description
- "Insert or move a data node after the data resource
- identified by the 'point' parameter.";
- }
- enum first {
- description
- "Insert or move a data node so it becomes ordered
- as the first entry.";
- }
- enum last {
- description
- "Insert or move a data node so it becomes ordered
- as the last entry.";
- }
-
- }
- default last;
- description
- "Identifies where a data resource will be inserted or
- moved. YANG only allows these operations for
- list and leaf-list data nodes that are ordered-by
- user.";
- }
-
- anyxml value {
- when "(../operation = 'create' or " +
- "../operation = 'merge' " +
- "or ../operation = 'replace' or " +
- "../operation = 'insert')" {
- description
- "Value node only used for create, merge,
- replace, and insert operations";
- }
- description
- "Value used for this edit operation.";
- }
- }
- }
-
- } // grouping yang-patch
-
-
- grouping yang-patch-status {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of
- YANG Patch status response message.";
-
- container yang-patch-status {
- description
- "A container representing the response message
- sent by the server after a YANG Patch edit
- request message has been processed.";
-
- leaf patch-id {
- type string;
- description
- "The patch-id value used in the request";
- }
-
- choice global-status {
- description
- "Report global errors or complete success.
- If there is no case selected then errors
- are reported in the edit-status container.";
-
- case global-errors {
- uses errors;
- description
- "This container will be present if global
- errors unrelated to a specific edit occurred.";
- }
- leaf ok {
- type empty;
- description
- "This leaf will be present if the request succeeded
- and there are no errors reported in the edit-status
- container.";
- }
- }
-
- container edit-status {
- description
- "This container will be present if there are
- edit-specific status responses to report.";
-
- list edit {
- key edit-id;
-
- description
- "Represents a list of status responses,
- corresponding to edits in the YANG Patch
- request message. If an edit entry was
- skipped or not reached by the server,
- then this list will not contain a corresponding
- entry for that edit.";
-
- leaf edit-id {
- type string;
- description
- "Response status is for the edit list entry
- with this edit-id value.";
- }
- choice edit-status-choice {
- description
- "A choice between different types of status
- responses for each edit entry.";
- leaf ok {
- type empty;
- description
- "This edit entry was invoked without any
- errors detected by the server associated
- with this edit.";
- }
- leaf location {
- type inet:uri;
- description
- "Contains the Location header value that would be
- returned if this edit causes a new resource to be
- created. If the edit identified by the same edit-id
- value was successfully invoked and a new resource
- was created, then this field will be returned
- instead of 'ok'.";
- }
- case errors {
- uses errors;
- description
- "The server detected errors associated with the
- edit identified by the same edit-id value.";
- }
- }
- }
- }
- }
- } // grouping yang-patch-status
-
-
- grouping errors {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of a
- YANG Patch errors report within a response message.";
-
- container errors {
- config false; // needed so list error does not need a key
- description
- "Represents an error report returned by the server if
- a request results in an error.";
-
- list error {
- description
- "An entry containing information about one
- specific error that occurred while processing
- a RESTCONF request.";
- reference "RFC 6241, Section 4.3";
-
- leaf error-type {
- type enumeration {
- enum transport {
- description "The transport layer";
- }
- enum rpc {
- description "The rpc or notification layer";
- }
- enum protocol {
- description "The protocol operation layer";
- }
- enum application {
- description "The server application layer";
- }
- }
- mandatory true;
- description
- "The protocol layer where the error occurred.";
- }
-
- leaf error-tag {
- type string;
- mandatory true;
- description
- "The enumerated error tag.";
- }
-
- leaf error-app-tag {
- type string;
- description
- "The application-specific error tag.";
- }
-
- leaf error-path {
- type data-resource-identifier;
- description
- "The target data resource identifier associated
- with the error, if any.";
- }
- leaf error-message {
- type string;
- description
- "A message describing the error.";
- }
-
- container error-info {
- description
- "A container allowing additional information
- to be included in the error report.";
- // arbitrary anyxml content here
- }
- }
- }
- } // grouping errors
-
-
- grouping restconf {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of
- the RESTCONF API resource.";
-
- container restconf {
- description
- "Conceptual container representing the
- application/yang.api resource type.";
-
- container config {
- description
- "Container representing the application/yang.datastore
- resource type. Represents the conceptual root of the
- unified configuration datastore containing YANG data
- nodes. The child nodes of this container are
- configuration data resources (application/yang.data)
- defined as top-level YANG data nodes from the modules
- advertised by the server in /restconf/modules.";
- }
-
- container operational {
- description
- "Container representing the application/yang.datastore
- resource type. Represents the conceptual root of the
- operational data supported by the server. The child
- nodes of this container are operational data resources
- (application/yang.data) defined as top-level
- YANG data nodes from the modules advertised by
- the server in /restconf/modules.";
- }
-
- container modules {
- description
- "Contains a list of module description entries.
- These modules are currently loaded into the server.";
-
- /** changed from list module to container module for testing purposes **/
- container module {
- description
- "Each entry represents one module currently
- supported by the server.";
-
- leaf name {
- type yang:yang-identifier;
- description "The YANG module name.";
- }
- leaf revision {
- type union {
- type revision-identifier;
- type string { length 0; }
- }
- description
- "The YANG module revision date. An empty string is
- used if no revision statement is present in the
- YANG module.";
- }
- leaf namespace {
- type inet:uri;
- mandatory true;
- description
- "The XML namespace identifier for this module.";
- }
- leaf-list feature {
- type yang:yang-identifier;
- description
- "List of YANG feature names from this module that are
- supported by the server.";
- }
- leaf-list deviation {
- type yang:yang-identifier;
- description
- "List of YANG deviation module names used by this
- server to modify the conformance of the module
- associated with this entry.";
- }
- }
- }
-
- container operations {
- description
- "Container for all operation resources
- (application/yang.operation),
-
- Each resource is represented as an empty leaf with the
- name of the RPC operation from the YANG rpc statement.
-
- E.g.;
-
- POST /restconf/operations/show-log-errors
-
- leaf show-log-errors {
- type empty;
- }
- ";
- }
-
- container streams {
- description
- "Container representing the notification event streams
- supported by the server.";
- reference
- "RFC 5277, Section 3.4, <streams> element.";
-
- list stream {
- key name;
- description
- "Each entry describes an event stream supported by
- the server.";
-
- leaf name {
- type string;
- description "The stream name";
- reference "RFC 5277, Section 3.4, <name> element.";
- }
-
- leaf description {
- type string;
- description "Description of stream content";
- reference
- "RFC 5277, Section 3.4, <description> element.";
- }
-
- leaf replay-support {
- type boolean;
- description
- "Indicates if replay buffer supported for this stream";
- reference
- "RFC 5277, Section 3.4, <replaySupport> element.";
- }
-
- leaf replay-log-creation-time {
- type yang:date-and-time;
- description
- "Indicates the time the replay log for this stream
- was created.";
- reference
- "RFC 5277, Section 3.4, <replayLogCreationTime>
- element.";
- }
-
- leaf events {
- type empty;
- description
- "Represents the entry point for establishing
- notification delivery via server sent events.";
- }
- }
- }
-
- leaf version {
- type enumeration {
- enum "1.0" {
- description
- "Version 1.0 of the RESTCONF protocol.";
- }
- }
- config false;
- description
- "Contains the RESTCONF protocol version.";
- }
- }
- } // grouping restconf
-
-
- grouping notification {
- description
- "Contains the notification message wrapper definition.";
-
- container notification {
- description
- "RESTCONF notification message wrapper.";
- leaf event-time {
- type yang:date-and-time;
- mandatory true;
- description
- "The time the event was generated by the
- event source.";
- reference
- "RFC 5277, section 4, <eventTime> element.";
- }
-
- /* The YANG-specific notification container is encoded
- * after the 'event-time' element. The format
- * corresponds to the notificationContent element
- * in RFC 5277, section 4. For example:
- *
- * module example-one {
- * ...
- * notification event1 { ... }
- *
- * }
- *
- * Encoded as element 'event1' in the namespace
- * for module 'example-one'.
- */
- }
- } // grouping notification
-
- }
\ No newline at end of file
+++ /dev/null
-module restconf-module-with-missing-container-modules {
- namespace "urn:ietf:params:xml:ns:yang:ietf-restconf";
- prefix "restconf";
-
- import ietf-yang-types { prefix yang; }
- import ietf-inet-types { prefix inet; }
-
- organization
- "IETF NETCONF (Network Configuration) Working Group";
-
- contact
- "Editor: Andy Bierman
- <mailto:andy@yumaworks.com>
-
- Editor: Martin Bjorklund
- <mailto:mbj@tail-f.com>
-
- Editor: Kent Watsen
- <mailto:kwatsen@juniper.net>
-
- Editor: Rex Fernando
- <mailto:rex@cisco.com>";
-
- description
- "This module contains conceptual YANG specifications
- for the YANG Patch and error content that is used in
- RESTCONF protocol messages. A conceptual container
- representing the RESTCONF API nodes (media type
- application/yang.api).
-
- Note that the YANG definitions within this module do not
- represent configuration data of any kind.
- The YANG grouping statements provide a normative syntax
- for XML and JSON message encoding purposes.
- 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 XXXX; see
- the RFC itself for full legal notices.";
-
- // RFC Ed.: replace XXXX with actual RFC number and remove this
- // note.
-
- // RFC Ed.: remove this note
- // Note: extracted from draft-bierman-netconf-restconf-02.txt
-
- // RFC Ed.: update the date below with the date of RFC publication
- // and remove this note.
- revision 2013-10-19 {
- description
- "Initial revision.";
- reference
- "RFC XXXX: RESTCONF Protocol.";
- }
-
- typedef data-resource-identifier {
- type string {
- length "1 .. max";
- }
- description
- "Contains a Data Resource Identifier formatted string
- to identify a specific data node. The data node that
- uses this data type SHOULD define the document root
- for data resource identifiers. The default document
- root is the target datastore conceptual root node.
- Data resource identifiers are defined relative to
- this document root.";
- reference
- "RFC XXXX: [sec. 5.3.1.1 ABNF For Data Resource Identifiers]";
- }
-
- // this typedef is TBD; not currently used
- typedef datastore-identifier {
- type union {
- type enumeration {
- enum candidate {
- description
- "Identifies the NETCONF shared candidate datastore.";
- reference
- "RFC 6241, section 8.3";
- }
- enum running {
- description
- "Identifies the NETCONF running datastore.";
- reference
- "RFC 6241, section 5.1";
- }
- enum startup {
- description
- "Identifies the NETCONF startup datastore.";
- reference
- "RFC 6241, section 8.7";
- }
- }
- type string;
- }
- description
- "Contains a string to identify a specific datastore.
- The enumerated datastore identifier values are
- reserved for standard datastore names.";
- }
-
- typedef revision-identifier {
- type string {
- pattern '\d{4}-\d{2}-\d{2}';
- }
- description
- "Represents a specific date in YYYY-MM-DD format.
- TBD: make pattern more precise to exclude leading zeros.";
- }
-
- grouping yang-patch {
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of a
- YANG Patch edit request message.";
-
- container yang-patch {
- description
- "Represents a conceptual sequence of datastore edits,
- called a patch. Each patch is given a client-assigned
- patch identifier. Each edit MUST be applied
- in ascending order, and all edits MUST be applied.
- If any errors occur, then the target datastore MUST NOT
- be changed by the patch operation.
-
- A patch MUST be validated by the server to be a
- well-formed message before any of the patch edits
- are validated or attempted.
-
- YANG datastore validation (defined in RFC 6020, section
- 8.3.3) is performed after all edits have been
- individually validated.
-
- It is possible for a datastore constraint violation to occur
- due to any node in the datastore, including nodes not
- included in the edit list. Any validation errors MUST
- be reported in the reply message.";
-
- reference
- "RFC 6020, section 8.3.";
-
- leaf patch-id {
- type string;
- description
- "An arbitrary string provided by the client to identify
- the entire patch. This value SHOULD be present in any
- audit logging records generated by the server for the
- patch. Error messages returned by the server pertaining
- to this patch will be identified by this patch-id value.";
- }
-
- leaf comment {
- type string {
- length "0 .. 1024";
- }
- description
- "An arbitrary string provided by the client to describe
- the entire patch. This value SHOULD be present in any
- audit logging records generated by the server for the
- patch.";
- }
-
- list edit {
- key edit-id;
- ordered-by user;
-
- description
- "Represents one edit within the YANG Patch
- request message.";
- leaf edit-id {
- type string;
- description
- "Arbitrary string index for the edit.
- Error messages returned by the server pertaining
- to a specific edit will be identified by this
- value.";
- }
-
- leaf operation {
- type enumeration {
- enum create {
- description
- "The target data node is created using the
- supplied value, only if it does not already
- exist.";
- }
- enum delete {
- description
- "Delete the target node, only if the data resource
- currently exists, otherwise return an error.";
- }
- enum insert {
- description
- "Insert the supplied value into a user-ordered
- list or leaf-list entry. The target node must
- represent a new data resource.";
- }
- enum merge {
- description
- "The supplied value is merged with the target data
- node.";
- }
- enum move {
- description
- "Move the target node. Reorder a user-ordered
- list or leaf-list. The target node must represent
- an existing data resource.";
- }
- enum replace {
- description
- "The supplied value is used to replace the target
- data node.";
- }
- enum remove {
- description
- "Delete the target node if it currently exists.";
- }
- }
- mandatory true;
- description
- "The datastore operation requested for the associated
- edit entry";
- }
-
- leaf target {
- type data-resource-identifier;
- mandatory true;
- description
- "Identifies the target data resource for the edit
- operation.";
- }
-
- leaf point {
- when "(../operation = 'insert' or " +
- "../operation = 'move') and " +
- "(../where = 'before' or ../where = 'after')" {
- description
- "Point leaf only applies for insert or move
- operations, before or after an existing entry.";
- }
- type data-resource-identifier;
- description
- "The absolute URL path for the data node that is being
- used as the insertion point or move point for the
- target of this edit entry.";
- }
-
- leaf where {
- when "../operation = 'insert' or ../operation = 'move'" {
- description
- "Where leaf only applies for insert or move
- operations.";
- }
- type enumeration {
- enum before {
- description
- "Insert or move a data node before the data resource
- identified by the 'point' parameter.";
- }
- enum after {
- description
- "Insert or move a data node after the data resource
- identified by the 'point' parameter.";
- }
- enum first {
- description
- "Insert or move a data node so it becomes ordered
- as the first entry.";
- }
- enum last {
- description
- "Insert or move a data node so it becomes ordered
- as the last entry.";
- }
-
- }
- default last;
- description
- "Identifies where a data resource will be inserted or
- moved. YANG only allows these operations for
- list and leaf-list data nodes that are ordered-by
- user.";
- }
-
- anyxml value {
- when "(../operation = 'create' or " +
- "../operation = 'merge' " +
- "or ../operation = 'replace' or " +
- "../operation = 'insert')" {
- description
- "Value node only used for create, merge,
- replace, and insert operations";
- }
- description
- "Value used for this edit operation.";
- }
- }
- }
-
- } // grouping yang-patch
-
-
- grouping yang-patch-status {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of
- YANG Patch status response message.";
-
- container yang-patch-status {
- description
- "A container representing the response message
- sent by the server after a YANG Patch edit
- request message has been processed.";
-
- leaf patch-id {
- type string;
- description
- "The patch-id value used in the request";
- }
-
- choice global-status {
- description
- "Report global errors or complete success.
- If there is no case selected then errors
- are reported in the edit-status container.";
-
- case global-errors {
- uses errors;
- description
- "This container will be present if global
- errors unrelated to a specific edit occurred.";
- }
- leaf ok {
- type empty;
- description
- "This leaf will be present if the request succeeded
- and there are no errors reported in the edit-status
- container.";
- }
- }
-
- container edit-status {
- description
- "This container will be present if there are
- edit-specific status responses to report.";
-
- list edit {
- key edit-id;
-
- description
- "Represents a list of status responses,
- corresponding to edits in the YANG Patch
- request message. If an edit entry was
- skipped or not reached by the server,
- then this list will not contain a corresponding
- entry for that edit.";
-
- leaf edit-id {
- type string;
- description
- "Response status is for the edit list entry
- with this edit-id value.";
- }
- choice edit-status-choice {
- description
- "A choice between different types of status
- responses for each edit entry.";
- leaf ok {
- type empty;
- description
- "This edit entry was invoked without any
- errors detected by the server associated
- with this edit.";
- }
- leaf location {
- type inet:uri;
- description
- "Contains the Location header value that would be
- returned if this edit causes a new resource to be
- created. If the edit identified by the same edit-id
- value was successfully invoked and a new resource
- was created, then this field will be returned
- instead of 'ok'.";
- }
- case errors {
- uses errors;
- description
- "The server detected errors associated with the
- edit identified by the same edit-id value.";
- }
- }
- }
- }
- }
- } // grouping yang-patch-status
-
-
- grouping errors {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of a
- YANG Patch errors report within a response message.";
-
- container errors {
- config false; // needed so list error does not need a key
- description
- "Represents an error report returned by the server if
- a request results in an error.";
-
- list error {
- description
- "An entry containing information about one
- specific error that occurred while processing
- a RESTCONF request.";
- reference "RFC 6241, Section 4.3";
-
- leaf error-type {
- type enumeration {
- enum transport {
- description "The transport layer";
- }
- enum rpc {
- description "The rpc or notification layer";
- }
- enum protocol {
- description "The protocol operation layer";
- }
- enum application {
- description "The server application layer";
- }
- }
- mandatory true;
- description
- "The protocol layer where the error occurred.";
- }
-
- leaf error-tag {
- type string;
- mandatory true;
- description
- "The enumerated error tag.";
- }
-
- leaf error-app-tag {
- type string;
- description
- "The application-specific error tag.";
- }
-
- leaf error-path {
- type data-resource-identifier;
- description
- "The target data resource identifier associated
- with the error, if any.";
- }
- leaf error-message {
- type string;
- description
- "A message describing the error.";
- }
-
- container error-info {
- description
- "A container allowing additional information
- to be included in the error report.";
- // arbitrary anyxml content here
- }
- }
- }
- } // grouping errors
-
-
- grouping restconf {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of
- the RESTCONF API resource.";
-
- container restconf {
- description
- "Conceptual container representing the
- application/yang.api resource type.";
-
- container config {
- description
- "Container representing the application/yang.datastore
- resource type. Represents the conceptual root of the
- unified configuration datastore containing YANG data
- nodes. The child nodes of this container are
- configuration data resources (application/yang.data)
- defined as top-level YANG data nodes from the modules
- advertised by the server in /restconf/modules.";
- }
-
- container operational {
- description
- "Container representing the application/yang.datastore
- resource type. Represents the conceptual root of the
- operational data supported by the server. The child
- nodes of this container are operational data resources
- (application/yang.data) defined as top-level
- YANG data nodes from the modules advertised by
- the server in /restconf/modules.";
- }
-
- // removed container modules for testing purposes
-
- container operations {
- description
- "Container for all operation resources
- (application/yang.operation),
-
- Each resource is represented as an empty leaf with the
- name of the RPC operation from the YANG rpc statement.
-
- E.g.;
-
- POST /restconf/operations/show-log-errors
-
- leaf show-log-errors {
- type empty;
- }
- ";
- }
-
- container streams {
- description
- "Container representing the notification event streams
- supported by the server.";
- reference
- "RFC 5277, Section 3.4, <streams> element.";
-
- list stream {
- key name;
- description
- "Each entry describes an event stream supported by
- the server.";
-
- leaf name {
- type string;
- description "The stream name";
- reference "RFC 5277, Section 3.4, <name> element.";
- }
-
- leaf description {
- type string;
- description "Description of stream content";
- reference
- "RFC 5277, Section 3.4, <description> element.";
- }
-
- leaf replay-support {
- type boolean;
- description
- "Indicates if replay buffer supported for this stream";
- reference
- "RFC 5277, Section 3.4, <replaySupport> element.";
- }
-
- leaf replay-log-creation-time {
- type yang:date-and-time;
- description
- "Indicates the time the replay log for this stream
- was created.";
- reference
- "RFC 5277, Section 3.4, <replayLogCreationTime>
- element.";
- }
-
- leaf events {
- type empty;
- description
- "Represents the entry point for establishing
- notification delivery via server sent events.";
- }
- }
- }
-
- leaf version {
- type enumeration {
- enum "1.0" {
- description
- "Version 1.0 of the RESTCONF protocol.";
- }
- }
- config false;
- description
- "Contains the RESTCONF protocol version.";
- }
- }
- } // grouping restconf
-
-
- grouping notification {
- description
- "Contains the notification message wrapper definition.";
-
- container notification {
- description
- "RESTCONF notification message wrapper.";
- leaf event-time {
- type yang:date-and-time;
- mandatory true;
- description
- "The time the event was generated by the
- event source.";
- reference
- "RFC 5277, section 4, <eventTime> element.";
- }
-
- /* The YANG-specific notification container is encoded
- * after the 'event-time' element. The format
- * corresponds to the notificationContent element
- * in RFC 5277, section 4. For example:
- *
- * module example-one {
- * ...
- * notification event1 { ... }
- *
- * }
- *
- * Encoded as element 'event1' in the namespace
- * for module 'example-one'.
- */
- }
- } // grouping notification
-
- }
\ No newline at end of file
+++ /dev/null
-module restconf-module-with-missing-list-module {
- namespace "urn:ietf:params:xml:ns:yang:ietf-restconf";
- prefix "restconf";
-
- import ietf-yang-types { prefix yang; }
- import ietf-inet-types { prefix inet; }
-
- organization
- "IETF NETCONF (Network Configuration) Working Group";
-
- contact
- "Editor: Andy Bierman
- <mailto:andy@yumaworks.com>
-
- Editor: Martin Bjorklund
- <mailto:mbj@tail-f.com>
-
- Editor: Kent Watsen
- <mailto:kwatsen@juniper.net>
-
- Editor: Rex Fernando
- <mailto:rex@cisco.com>";
-
- description
- "This module contains conceptual YANG specifications
- for the YANG Patch and error content that is used in
- RESTCONF protocol messages. A conceptual container
- representing the RESTCONF API nodes (media type
- application/yang.api).
-
- Note that the YANG definitions within this module do not
- represent configuration data of any kind.
- The YANG grouping statements provide a normative syntax
- for XML and JSON message encoding purposes.
- 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 XXXX; see
- the RFC itself for full legal notices.";
-
- // RFC Ed.: replace XXXX with actual RFC number and remove this
- // note.
-
- // RFC Ed.: remove this note
- // Note: extracted from draft-bierman-netconf-restconf-02.txt
-
- // RFC Ed.: update the date below with the date of RFC publication
- // and remove this note.
- revision 2013-10-19 {
- description
- "Initial revision.";
- reference
- "RFC XXXX: RESTCONF Protocol.";
- }
-
- typedef data-resource-identifier {
- type string {
- length "1 .. max";
- }
- description
- "Contains a Data Resource Identifier formatted string
- to identify a specific data node. The data node that
- uses this data type SHOULD define the document root
- for data resource identifiers. The default document
- root is the target datastore conceptual root node.
- Data resource identifiers are defined relative to
- this document root.";
- reference
- "RFC XXXX: [sec. 5.3.1.1 ABNF For Data Resource Identifiers]";
- }
-
- // this typedef is TBD; not currently used
- typedef datastore-identifier {
- type union {
- type enumeration {
- enum candidate {
- description
- "Identifies the NETCONF shared candidate datastore.";
- reference
- "RFC 6241, section 8.3";
- }
- enum running {
- description
- "Identifies the NETCONF running datastore.";
- reference
- "RFC 6241, section 5.1";
- }
- enum startup {
- description
- "Identifies the NETCONF startup datastore.";
- reference
- "RFC 6241, section 8.7";
- }
- }
- type string;
- }
- description
- "Contains a string to identify a specific datastore.
- The enumerated datastore identifier values are
- reserved for standard datastore names.";
- }
-
- typedef revision-identifier {
- type string {
- pattern '\d{4}-\d{2}-\d{2}';
- }
- description
- "Represents a specific date in YYYY-MM-DD format.
- TBD: make pattern more precise to exclude leading zeros.";
- }
-
- grouping yang-patch {
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of a
- YANG Patch edit request message.";
-
- container yang-patch {
- description
- "Represents a conceptual sequence of datastore edits,
- called a patch. Each patch is given a client-assigned
- patch identifier. Each edit MUST be applied
- in ascending order, and all edits MUST be applied.
- If any errors occur, then the target datastore MUST NOT
- be changed by the patch operation.
-
- A patch MUST be validated by the server to be a
- well-formed message before any of the patch edits
- are validated or attempted.
-
- YANG datastore validation (defined in RFC 6020, section
- 8.3.3) is performed after all edits have been
- individually validated.
-
- It is possible for a datastore constraint violation to occur
- due to any node in the datastore, including nodes not
- included in the edit list. Any validation errors MUST
- be reported in the reply message.";
-
- reference
- "RFC 6020, section 8.3.";
-
- leaf patch-id {
- type string;
- description
- "An arbitrary string provided by the client to identify
- the entire patch. This value SHOULD be present in any
- audit logging records generated by the server for the
- patch. Error messages returned by the server pertaining
- to this patch will be identified by this patch-id value.";
- }
-
- leaf comment {
- type string {
- length "0 .. 1024";
- }
- description
- "An arbitrary string provided by the client to describe
- the entire patch. This value SHOULD be present in any
- audit logging records generated by the server for the
- patch.";
- }
-
- list edit {
- key edit-id;
- ordered-by user;
-
- description
- "Represents one edit within the YANG Patch
- request message.";
- leaf edit-id {
- type string;
- description
- "Arbitrary string index for the edit.
- Error messages returned by the server pertaining
- to a specific edit will be identified by this
- value.";
- }
-
- leaf operation {
- type enumeration {
- enum create {
- description
- "The target data node is created using the
- supplied value, only if it does not already
- exist.";
- }
- enum delete {
- description
- "Delete the target node, only if the data resource
- currently exists, otherwise return an error.";
- }
- enum insert {
- description
- "Insert the supplied value into a user-ordered
- list or leaf-list entry. The target node must
- represent a new data resource.";
- }
- enum merge {
- description
- "The supplied value is merged with the target data
- node.";
- }
- enum move {
- description
- "Move the target node. Reorder a user-ordered
- list or leaf-list. The target node must represent
- an existing data resource.";
- }
- enum replace {
- description
- "The supplied value is used to replace the target
- data node.";
- }
- enum remove {
- description
- "Delete the target node if it currently exists.";
- }
- }
- mandatory true;
- description
- "The datastore operation requested for the associated
- edit entry";
- }
-
- leaf target {
- type data-resource-identifier;
- mandatory true;
- description
- "Identifies the target data resource for the edit
- operation.";
- }
-
- leaf point {
- when "(../operation = 'insert' or " +
- "../operation = 'move') and " +
- "(../where = 'before' or ../where = 'after')" {
- description
- "Point leaf only applies for insert or move
- operations, before or after an existing entry.";
- }
- type data-resource-identifier;
- description
- "The absolute URL path for the data node that is being
- used as the insertion point or move point for the
- target of this edit entry.";
- }
-
- leaf where {
- when "../operation = 'insert' or ../operation = 'move'" {
- description
- "Where leaf only applies for insert or move
- operations.";
- }
- type enumeration {
- enum before {
- description
- "Insert or move a data node before the data resource
- identified by the 'point' parameter.";
- }
- enum after {
- description
- "Insert or move a data node after the data resource
- identified by the 'point' parameter.";
- }
- enum first {
- description
- "Insert or move a data node so it becomes ordered
- as the first entry.";
- }
- enum last {
- description
- "Insert or move a data node so it becomes ordered
- as the last entry.";
- }
-
- }
- default last;
- description
- "Identifies where a data resource will be inserted or
- moved. YANG only allows these operations for
- list and leaf-list data nodes that are ordered-by
- user.";
- }
-
- anyxml value {
- when "(../operation = 'create' or " +
- "../operation = 'merge' " +
- "or ../operation = 'replace' or " +
- "../operation = 'insert')" {
- description
- "Value node only used for create, merge,
- replace, and insert operations";
- }
- description
- "Value used for this edit operation.";
- }
- }
- }
-
- } // grouping yang-patch
-
-
- grouping yang-patch-status {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of
- YANG Patch status response message.";
-
- container yang-patch-status {
- description
- "A container representing the response message
- sent by the server after a YANG Patch edit
- request message has been processed.";
-
- leaf patch-id {
- type string;
- description
- "The patch-id value used in the request";
- }
-
- choice global-status {
- description
- "Report global errors or complete success.
- If there is no case selected then errors
- are reported in the edit-status container.";
-
- case global-errors {
- uses errors;
- description
- "This container will be present if global
- errors unrelated to a specific edit occurred.";
- }
- leaf ok {
- type empty;
- description
- "This leaf will be present if the request succeeded
- and there are no errors reported in the edit-status
- container.";
- }
- }
-
- container edit-status {
- description
- "This container will be present if there are
- edit-specific status responses to report.";
-
- list edit {
- key edit-id;
-
- description
- "Represents a list of status responses,
- corresponding to edits in the YANG Patch
- request message. If an edit entry was
- skipped or not reached by the server,
- then this list will not contain a corresponding
- entry for that edit.";
-
- leaf edit-id {
- type string;
- description
- "Response status is for the edit list entry
- with this edit-id value.";
- }
- choice edit-status-choice {
- description
- "A choice between different types of status
- responses for each edit entry.";
- leaf ok {
- type empty;
- description
- "This edit entry was invoked without any
- errors detected by the server associated
- with this edit.";
- }
- leaf location {
- type inet:uri;
- description
- "Contains the Location header value that would be
- returned if this edit causes a new resource to be
- created. If the edit identified by the same edit-id
- value was successfully invoked and a new resource
- was created, then this field will be returned
- instead of 'ok'.";
- }
- case errors {
- uses errors;
- description
- "The server detected errors associated with the
- edit identified by the same edit-id value.";
- }
- }
- }
- }
- }
- } // grouping yang-patch-status
-
-
- grouping errors {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of a
- YANG Patch errors report within a response message.";
-
- container errors {
- config false; // needed so list error does not need a key
- description
- "Represents an error report returned by the server if
- a request results in an error.";
-
- list error {
- description
- "An entry containing information about one
- specific error that occurred while processing
- a RESTCONF request.";
- reference "RFC 6241, Section 4.3";
-
- leaf error-type {
- type enumeration {
- enum transport {
- description "The transport layer";
- }
- enum rpc {
- description "The rpc or notification layer";
- }
- enum protocol {
- description "The protocol operation layer";
- }
- enum application {
- description "The server application layer";
- }
- }
- mandatory true;
- description
- "The protocol layer where the error occurred.";
- }
-
- leaf error-tag {
- type string;
- mandatory true;
- description
- "The enumerated error tag.";
- }
-
- leaf error-app-tag {
- type string;
- description
- "The application-specific error tag.";
- }
-
- leaf error-path {
- type data-resource-identifier;
- description
- "The target data resource identifier associated
- with the error, if any.";
- }
- leaf error-message {
- type string;
- description
- "A message describing the error.";
- }
-
- container error-info {
- description
- "A container allowing additional information
- to be included in the error report.";
- // arbitrary anyxml content here
- }
- }
- }
- } // grouping errors
-
-
- grouping restconf {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of
- the RESTCONF API resource.";
-
- container restconf {
- description
- "Conceptual container representing the
- application/yang.api resource type.";
-
- container config {
- description
- "Container representing the application/yang.datastore
- resource type. Represents the conceptual root of the
- unified configuration datastore containing YANG data
- nodes. The child nodes of this container are
- configuration data resources (application/yang.data)
- defined as top-level YANG data nodes from the modules
- advertised by the server in /restconf/modules.";
- }
-
- container operational {
- description
- "Container representing the application/yang.datastore
- resource type. Represents the conceptual root of the
- operational data supported by the server. The child
- nodes of this container are operational data resources
- (application/yang.data) defined as top-level
- YANG data nodes from the modules advertised by
- the server in /restconf/modules.";
- }
-
- container modules {
- description
- "Contains a list of module description entries.
- These modules are currently loaded into the server.";
-
- // removed list module for testing purposes + added list test-list
- list test-list {
- leaf test-leaf {
- type string;
- }
- }
- }
-
- container operations {
- description
- "Container for all operation resources
- (application/yang.operation),
-
- Each resource is represented as an empty leaf with the
- name of the RPC operation from the YANG rpc statement.
-
- E.g.;
-
- POST /restconf/operations/show-log-errors
-
- leaf show-log-errors {
- type empty;
- }
- ";
- }
-
- container streams {
- description
- "Container representing the notification event streams
- supported by the server.";
- reference
- "RFC 5277, Section 3.4, <streams> element.";
-
- list stream {
- key name;
- description
- "Each entry describes an event stream supported by
- the server.";
-
- leaf name {
- type string;
- description "The stream name";
- reference "RFC 5277, Section 3.4, <name> element.";
- }
-
- leaf description {
- type string;
- description "Description of stream content";
- reference
- "RFC 5277, Section 3.4, <description> element.";
- }
-
- leaf replay-support {
- type boolean;
- description
- "Indicates if replay buffer supported for this stream";
- reference
- "RFC 5277, Section 3.4, <replaySupport> element.";
- }
-
- leaf replay-log-creation-time {
- type yang:date-and-time;
- description
- "Indicates the time the replay log for this stream
- was created.";
- reference
- "RFC 5277, Section 3.4, <replayLogCreationTime>
- element.";
- }
-
- leaf events {
- type empty;
- description
- "Represents the entry point for establishing
- notification delivery via server sent events.";
- }
- }
- }
-
- leaf version {
- type enumeration {
- enum "1.0" {
- description
- "Version 1.0 of the RESTCONF protocol.";
- }
- }
- config false;
- description
- "Contains the RESTCONF protocol version.";
- }
- }
- } // grouping restconf
-
-
- grouping notification {
- description
- "Contains the notification message wrapper definition.";
-
- container notification {
- description
- "RESTCONF notification message wrapper.";
- leaf event-time {
- type yang:date-and-time;
- mandatory true;
- description
- "The time the event was generated by the
- event source.";
- reference
- "RFC 5277, section 4, <eventTime> element.";
- }
-
- /* The YANG-specific notification container is encoded
- * after the 'event-time' element. The format
- * corresponds to the notificationContent element
- * in RFC 5277, section 4. For example:
- *
- * module example-one {
- * ...
- * notification event1 { ... }
- *
- * }
- *
- * Encoded as element 'event1' in the namespace
- * for module 'example-one'.
- */
- }
- } // grouping notification
-
- }
\ No newline at end of file
+++ /dev/null
- 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)";
- }
-
- }
+++ /dev/null
-module ietf-restconf {
- namespace "urn:ietf:params:xml:ns:yang:ietf-restconf";
- prefix "restconf";
-
- import ietf-yang-types { prefix yang; }
- import ietf-inet-types { prefix inet; }
-
- organization
- "IETF NETCONF (Network Configuration) Working Group";
-
- contact
- "Editor: Andy Bierman
- <mailto:andy@yumaworks.com>
-
- Editor: Martin Bjorklund
- <mailto:mbj@tail-f.com>
-
- Editor: Kent Watsen
- <mailto:kwatsen@juniper.net>
-
- Editor: Rex Fernando
- <mailto:rex@cisco.com>";
-
- description
- "This module contains conceptual YANG specifications
- for the YANG Patch and error content that is used in
- RESTCONF protocol messages. A conceptual container
- representing the RESTCONF API nodes (media type
- application/yang.api).
-
- Note that the YANG definitions within this module do not
- represent configuration data of any kind.
- The YANG grouping statements provide a normative syntax
- for XML and JSON message encoding purposes.
- 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 XXXX; see
- the RFC itself for full legal notices.";
-
- // RFC Ed.: replace XXXX with actual RFC number and remove this
- // note.
-
- // RFC Ed.: remove this note
- // Note: extracted from draft-bierman-netconf-restconf-02.txt
-
- // RFC Ed.: update the date below with the date of RFC publication
- // and remove this note.
- revision 2013-10-19 {
- description
- "Initial revision.";
- reference
- "RFC XXXX: RESTCONF Protocol.";
- }
-
- typedef data-resource-identifier {
- type string {
- length "1 .. max";
- }
- description
- "Contains a Data Resource Identifier formatted string
- to identify a specific data node. The data node that
- uses this data type SHOULD define the document root
- for data resource identifiers. The default document
- root is the target datastore conceptual root node.
- Data resource identifiers are defined relative to
- this document root.";
- reference
- "RFC XXXX: [sec. 5.3.1.1 ABNF For Data Resource Identifiers]";
- }
-
- // this typedef is TBD; not currently used
- typedef datastore-identifier {
- type union {
- type enumeration {
- enum candidate {
- description
- "Identifies the NETCONF shared candidate datastore.";
- reference
- "RFC 6241, section 8.3";
- }
- enum running {
- description
- "Identifies the NETCONF running datastore.";
- reference
- "RFC 6241, section 5.1";
- }
- enum startup {
- description
- "Identifies the NETCONF startup datastore.";
- reference
- "RFC 6241, section 8.7";
- }
- }
- type string;
- }
- description
- "Contains a string to identify a specific datastore.
- The enumerated datastore identifier values are
- reserved for standard datastore names.";
- }
-
- typedef revision-identifier {
- type string {
- pattern '\d{4}-\d{2}-\d{2}';
- }
- description
- "Represents a specific date in YYYY-MM-DD format.
- TBD: make pattern more precise to exclude leading zeros.";
- }
-
- grouping yang-patch {
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of a
- YANG Patch edit request message.";
-
- container yang-patch {
- description
- "Represents a conceptual sequence of datastore edits,
- called a patch. Each patch is given a client-assigned
- patch identifier. Each edit MUST be applied
- in ascending order, and all edits MUST be applied.
- If any errors occur, then the target datastore MUST NOT
- be changed by the patch operation.
-
- A patch MUST be validated by the server to be a
- well-formed message before any of the patch edits
- are validated or attempted.
-
- YANG datastore validation (defined in RFC 6020, section
- 8.3.3) is performed after all edits have been
- individually validated.
-
- It is possible for a datastore constraint violation to occur
- due to any node in the datastore, including nodes not
- included in the edit list. Any validation errors MUST
- be reported in the reply message.";
-
- reference
- "RFC 6020, section 8.3.";
-
- leaf patch-id {
- type string;
- description
- "An arbitrary string provided by the client to identify
- the entire patch. This value SHOULD be present in any
- audit logging records generated by the server for the
- patch. Error messages returned by the server pertaining
- to this patch will be identified by this patch-id value.";
- }
-
- leaf comment {
- type string {
- length "0 .. 1024";
- }
- description
- "An arbitrary string provided by the client to describe
- the entire patch. This value SHOULD be present in any
- audit logging records generated by the server for the
- patch.";
- }
-
- list edit {
- key edit-id;
- ordered-by user;
-
- description
- "Represents one edit within the YANG Patch
- request message.";
- leaf edit-id {
- type string;
- description
- "Arbitrary string index for the edit.
- Error messages returned by the server pertaining
- to a specific edit will be identified by this
- value.";
- }
-
- leaf operation {
- type enumeration {
- enum create {
- description
- "The target data node is created using the
- supplied value, only if it does not already
- exist.";
- }
- enum delete {
- description
- "Delete the target node, only if the data resource
- currently exists, otherwise return an error.";
- }
- enum insert {
- description
- "Insert the supplied value into a user-ordered
- list or leaf-list entry. The target node must
- represent a new data resource.";
- }
- enum merge {
- description
- "The supplied value is merged with the target data
- node.";
- }
- enum move {
- description
- "Move the target node. Reorder a user-ordered
- list or leaf-list. The target node must represent
- an existing data resource.";
- }
- enum replace {
- description
- "The supplied value is used to replace the target
- data node.";
- }
- enum remove {
- description
- "Delete the target node if it currently exists.";
- }
- }
- mandatory true;
- description
- "The datastore operation requested for the associated
- edit entry";
- }
-
- leaf target {
- type data-resource-identifier;
- mandatory true;
- description
- "Identifies the target data resource for the edit
- operation.";
- }
-
- leaf point {
- when "(../operation = 'insert' or " +
- "../operation = 'move') and " +
- "(../where = 'before' or ../where = 'after')" {
- description
- "Point leaf only applies for insert or move
- operations, before or after an existing entry.";
- }
- type data-resource-identifier;
- description
- "The absolute URL path for the data node that is being
- used as the insertion point or move point for the
- target of this edit entry.";
- }
-
- leaf where {
- when "../operation = 'insert' or ../operation = 'move'" {
- description
- "Where leaf only applies for insert or move
- operations.";
- }
- type enumeration {
- enum before {
- description
- "Insert or move a data node before the data resource
- identified by the 'point' parameter.";
- }
- enum after {
- description
- "Insert or move a data node after the data resource
- identified by the 'point' parameter.";
- }
- enum first {
- description
- "Insert or move a data node so it becomes ordered
- as the first entry.";
- }
- enum last {
- description
- "Insert or move a data node so it becomes ordered
- as the last entry.";
- }
-
- }
- default last;
- description
- "Identifies where a data resource will be inserted or
- moved. YANG only allows these operations for
- list and leaf-list data nodes that are ordered-by
- user.";
- }
-
- anyxml value {
- when "(../operation = 'create' or " +
- "../operation = 'merge' " +
- "or ../operation = 'replace' or " +
- "../operation = 'insert')" {
- description
- "Value node only used for create, merge,
- replace, and insert operations";
- }
- description
- "Value used for this edit operation.";
- }
- }
- }
-
- } // grouping yang-patch
-
-
- grouping yang-patch-status {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of
- YANG Patch status response message.";
-
- container yang-patch-status {
- description
- "A container representing the response message
- sent by the server after a YANG Patch edit
- request message has been processed.";
-
- leaf patch-id {
- type string;
- description
- "The patch-id value used in the request";
- }
-
- choice global-status {
- description
- "Report global errors or complete success.
- If there is no case selected then errors
- are reported in the edit-status container.";
-
- case global-errors {
- uses errors;
- description
- "This container will be present if global
- errors unrelated to a specific edit occurred.";
- }
- leaf ok {
- type empty;
- description
- "This leaf will be present if the request succeeded
- and there are no errors reported in the edit-status
- container.";
- }
- }
-
- container edit-status {
- description
- "This container will be present if there are
- edit-specific status responses to report.";
-
- list edit {
- key edit-id;
-
- description
- "Represents a list of status responses,
- corresponding to edits in the YANG Patch
- request message. If an edit entry was
- skipped or not reached by the server,
- then this list will not contain a corresponding
- entry for that edit.";
-
- leaf edit-id {
- type string;
- description
- "Response status is for the edit list entry
- with this edit-id value.";
- }
- choice edit-status-choice {
- description
- "A choice between different types of status
- responses for each edit entry.";
- leaf ok {
- type empty;
- description
- "This edit entry was invoked without any
- errors detected by the server associated
- with this edit.";
- }
- leaf location {
- type inet:uri;
- description
- "Contains the Location header value that would be
- returned if this edit causes a new resource to be
- created. If the edit identified by the same edit-id
- value was successfully invoked and a new resource
- was created, then this field will be returned
- instead of 'ok'.";
- }
- case errors {
- uses errors;
- description
- "The server detected errors associated with the
- edit identified by the same edit-id value.";
- }
- }
- }
- }
- }
- } // grouping yang-patch-status
-
-
- grouping errors {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of a
- YANG Patch errors report within a response message.";
-
- container errors {
- config false; // needed so list error does not need a key
- description
- "Represents an error report returned by the server if
- a request results in an error.";
-
- list error {
- description
- "An entry containing information about one
- specific error that occurred while processing
- a RESTCONF request.";
- reference "RFC 6241, Section 4.3";
-
- leaf error-type {
- type enumeration {
- enum transport {
- description "The transport layer";
- }
- enum rpc {
- description "The rpc or notification layer";
- }
- enum protocol {
- description "The protocol operation layer";
- }
- enum application {
- description "The server application layer";
- }
- }
- mandatory true;
- description
- "The protocol layer where the error occurred.";
- }
-
- leaf error-tag {
- type string;
- mandatory true;
- description
- "The enumerated error tag.";
- }
-
- leaf error-app-tag {
- type string;
- description
- "The application-specific error tag.";
- }
-
- leaf error-path {
- type data-resource-identifier;
- description
- "The target data resource identifier associated
- with the error, if any.";
- }
- leaf error-message {
- type string;
- description
- "A message describing the error.";
- }
-
- container error-info {
- description
- "A container allowing additional information
- to be included in the error report.";
- // arbitrary anyxml content here
- }
- }
- }
- } // grouping errors
-
-
- grouping restconf {
-
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of
- the RESTCONF API resource.";
-
- container restconf {
- description
- "Conceptual container representing the
- application/yang.api resource type.";
-
- container config {
- description
- "Container representing the application/yang.datastore
- resource type. Represents the conceptual root of the
- unified configuration datastore containing YANG data
- nodes. The child nodes of this container are
- configuration data resources (application/yang.data)
- defined as top-level YANG data nodes from the modules
- advertised by the server in /restconf/modules.";
- }
-
- container operational {
- description
- "Container representing the application/yang.datastore
- resource type. Represents the conceptual root of the
- operational data supported by the server. The child
- nodes of this container are operational data resources
- (application/yang.data) defined as top-level
- YANG data nodes from the modules advertised by
- the server in /restconf/modules.";
- }
-
- container modules {
- description
- "Contains a list of module description entries.
- These modules are currently loaded into the server.";
-
- list module {
- key "name revision";
- description
- "Each entry represents one module currently
- supported by the server.";
-
- leaf name {
- type yang:yang-identifier;
- description "The YANG module name.";
- }
- leaf revision {
- type union {
- type revision-identifier;
- type string { length 0; }
- }
- description
- "The YANG module revision date. An empty string is
- used if no revision statement is present in the
- YANG module.";
- }
- leaf namespace {
- type inet:uri;
- mandatory true;
- description
- "The XML namespace identifier for this module.";
- }
- leaf-list feature {
- type yang:yang-identifier;
- description
- "List of YANG feature names from this module that are
- supported by the server.";
- }
- leaf-list deviation {
- type yang:yang-identifier;
- description
- "List of YANG deviation module names used by this
- server to modify the conformance of the module
- associated with this entry.";
- }
- }
- }
-
- container operations {
- description
- "Container for all operation resources
- (application/yang.operation),
-
- Each resource is represented as an empty leaf with the
- name of the RPC operation from the YANG rpc statement.
-
- E.g.;
-
- POST /restconf/operations/show-log-errors
-
- leaf show-log-errors {
- type empty;
- }
- ";
- }
-
- container streams {
- description
- "Container representing the notification event streams
- supported by the server.";
- reference
- "RFC 5277, Section 3.4, <streams> element.";
-
- list stream {
- key name;
- description
- "Each entry describes an event stream supported by
- the server.";
-
- leaf name {
- type string;
- description "The stream name";
- reference "RFC 5277, Section 3.4, <name> element.";
- }
-
- leaf description {
- type string;
- description "Description of stream content";
- reference
- "RFC 5277, Section 3.4, <description> element.";
- }
-
- leaf replay-support {
- type boolean;
- description
- "Indicates if replay buffer supported for this stream";
- reference
- "RFC 5277, Section 3.4, <replaySupport> element.";
- }
-
- leaf replay-log-creation-time {
- type yang:date-and-time;
- description
- "Indicates the time the replay log for this stream
- was created.";
- reference
- "RFC 5277, Section 3.4, <replayLogCreationTime>
- element.";
- }
-
- leaf events {
- type empty;
- description
- "Represents the entry point for establishing
- notification delivery via server sent events.";
- }
- }
- }
-
- leaf version {
- type enumeration {
- enum "1.0" {
- description
- "Version 1.0 of the RESTCONF protocol.";
- }
- }
- config false;
- description
- "Contains the RESTCONF protocol version.";
- }
- }
- } // grouping restconf
-
-
- grouping notification {
- description
- "Contains the notification message wrapper definition.";
-
- container notification {
- description
- "RESTCONF notification message wrapper.";
- leaf event-time {
- type yang:date-and-time;
- mandatory true;
- description
- "The time the event was generated by the
- event source.";
- reference
- "RFC 5277, section 4, <eventTime> element.";
- }
-
- /* The YANG-specific notification container is encoded
- * after the 'event-time' element. The format
- * corresponds to the notificationContent element
- * in RFC 5277, section 4. For example:
- *
- * module example-one {
- * ...
- * notification event1 { ... }
- *
- * }
- *
- * Encoded as element 'event1' in the namespace
- * for module 'example-one'.
- */
- }
- } // grouping notification
-
- }
\ No newline at end of file
+++ /dev/null
-module ietf-yang-library {
- namespace "urn:ietf:params:xml:ns:yang:ietf-yang-library";
- prefix "yanglib";
- import ietf-yang-types {
- prefix yang;
- }
- import ietf-inet-types {
- prefix inet;
- }
- organization
- "IETF NETCONF (Network Configuration) Working Group";
- contact
- "WG Web: <https://datatracker.ietf.org/wg/netconf/>
- WG List: <mailto:netconf@ietf.org>
- WG Chair: Mehmet Ersue
- <mailto:mehmet.ersue@nsn.com>
- WG Chair: Mahesh Jethanandani
- <mailto:mjethanandani@gmail.com>
- Editor: Andy Bierman
- <mailto:andy@yumaworks.com>
- Editor: Martin Bjorklund
- <mailto:mbj@tail-f.com>
- Editor: Kent Watsen
- <mailto:kwatsen@juniper.net>";
- description
- "This module contains monitoring information about the YANG
- modules and submodules that are used within a YANG-based
- server.
- Copyright (c) 2016 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 7895; see
- the RFC itself for full legal notices.";
- revision 2016-06-21 {
- description
- "Initial revision.";
- reference
- "RFC 7895: YANG Module Library.";
- }
- /*
- * Typedefs
- */
- typedef revision-identifier {
- type string {
- pattern '\d{4}-\d{2}-\d{2}';
- }
- description
- "Represents a specific date in YYYY-MM-DD format.";
- }
- /*
- * Groupings
- */
- grouping module-list {
- description
- "The module data structure is represented as a grouping
- so it can be reused in configuration or another monitoring
- data structure.";
- grouping common-leafs {
- description
- "Common parameters for YANG modules and submodules.";
- leaf name {
- type yang:yang-identifier;
- description
- "The YANG module or submodule name.";
- }
- leaf revision {
- type union {
- type revision-identifier;
- type string { length 0; }
- }
- description
- "The YANG module or submodule revision date.
- A zero-length string is used if no revision statement
- is present in the YANG module or submodule.";
- }
- }
- grouping schema-leaf {
- description
- "Common schema leaf parameter for modules and submodules.";
- leaf schema {
- type inet:uri;
- description
- "Contains a URL that represents the YANG schema
- resource for this module or submodule.
- This leaf will only be present if there is a URL
- available for retrieval of the schema for this entry.";
- }
- }
- list module {
- key "name revision";
- description
- "Each entry represents one revision of one module
- currently supported by the server.";
- uses common-leafs;
- uses schema-leaf;
- leaf namespace {
- type inet:uri;
- mandatory true;
- description
- "The XML namespace identifier for this module.";
- }
- leaf-list feature {
- type yang:yang-identifier;
- description
- "List of YANG feature names from this module that are
- supported by the server, regardless of whether they are
- defined in the module or any included submodule.";
- }
- list deviation {
- key "name revision";
- description
- "List of YANG deviation module names and revisions
- used by this server to modify the conformance of
- the module associated with this entry. Note that
- the same module can be used for deviations for
- multiple modules, so the same entry MAY appear
- within multiple 'module' entries.
- The deviation module MUST be present in the 'module'
- list, with the same name and revision values.
- The 'conformance-type' value will be 'implement' for
- the deviation module.";
- uses common-leafs;
- }
- leaf conformance-type {
- type enumeration {
- enum implement {
- description
- "Indicates that the server implements one or more
- protocol-accessible objects defined in the YANG module
- identified in this entry. This includes deviation
- statements defined in the module.
- For YANG version 1.1 modules, there is at most one
- module entry with conformance type 'implement' for a
- particular module name, since YANG 1.1 requires that,
- at most, one revision of a module is implemented.
- For YANG version 1 modules, there SHOULD NOT be more
- than one module entry for a particular module name.";
- }
- enum import {
- description
- "Indicates that the server imports reusable definitions
- from the specified revision of the module but does
- not implement any protocol-accessible objects from
- this revision.
- Multiple module entries for the same module name MAY
- exist. This can occur if multiple modules import the
- same module but specify different revision dates in
- the import statements.";
- }
- }
- mandatory true;
- description
- "Indicates the type of conformance the server is claiming
- for the YANG module identified by this entry.";
- }
- list submodule {
- key "name revision";
- description
- "Each entry represents one submodule within the
- parent module.";
- uses common-leafs;
- uses schema-leaf;
- }
- }
- }
- /*
- * Operational state data nodes
- */
- container modules-state {
- config false;
- description
- "Contains YANG module monitoring information.";
- leaf module-set-id {
- type string;
- mandatory true;
- description
- "Contains a server-specific identifier representing
- the current set of modules and submodules. The
- server MUST change the value of this leaf if the
- information represented by the 'module' list instances
- has changed.";
- }
- uses module-list;
- }
- /*
- * Notifications
- */
- notification yang-library-change {
- description
- "Generated when the set of modules and submodules supported
- by the server has changed.";
- leaf module-set-id {
- type leafref {
- path "/yanglib:modules-state/yanglib:module-set-id";
- }
- mandatory true;
- description
- "Contains the module-set-id value representing the
- set of modules and submodules supported at the server at
- the time the notification is generated.";
- }
- }
-}
+++ /dev/null
- 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)";
- }
-
- 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 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";
- }
-
- }
+++ /dev/null
-module multiple-nodes {
- namespace "multiple:nodes";
- prefix "mod1";
- revision "2014-06-23";
-
- container cont {
- container cont1 {
- leaf lf11 {
- type string;
- }
- }
-
- leaf lf1 {
- type string;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-module augment-container {
- namespace "ns:augment:container";
- prefix "augcont";
-
-
- import yang {prefix yng; revision-date 2013-11-26;}
-
-
- revision "2013-11-26" {
- }
-
- augment "/yng:cont" {
- container cont1 {
- leaf lf11 {
- type string;
- }
- }
- }
-
-
-
-}
\ No newline at end of file
+++ /dev/null
-module augment-leaf {
- namespace "ns:augment:leaf";
- prefix "auglf";
-
-
- import yang {prefix yng; revision-date 2013-11-26;}
-
-
- revision "2013-11-26" {
- }
-
- augment "/yng:cont" {
- leaf lf2 {
- type string;
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-module augment-leaflist {
- namespace "ns:augment:leaflist";
- prefix "auglflst";
-
-
- import yang {prefix yng; revision-date 2013-11-26;}
-
-
- revision "2013-11-26" {
- }
-
- augment "/yng:cont" {
- leaf-list lflst1 {
- type string;
- }
- }
-
-
-
-}
\ No newline at end of file
+++ /dev/null
-module augment-list {
- namespace "ns:augment:list";
- prefix "auglst";
-
-
- import yang {prefix yng; revision-date 2013-11-26;}
-
-
- revision "2013-11-26" {
- }
-
- augment "/yng:cont" {
- list lst1 {
- leaf lf11 {
- type string;
- }
- }
- }
-
-
-
-}
\ No newline at end of file
+++ /dev/null
-<cont xmlns="ns:yang">
- <lf1>lf1</lf1>
- <lf2>lf2</lf2>
- <cont1>
- <lf11>lf11</lf11>
- </cont1>
- <lst1>
- <lf11>lf1_1</lf11>
- </lst1>
- <lst1>
- <lf11>lf1_2</lf11>
- </lst1>
- <lflst1>lflst1_1</lflst1>
- <lflst1>lflst1_2</lflst1>
- <lflst1>lflst1_3</lflst1>
-</cont>
\ No newline at end of file
+++ /dev/null
-module yang {
- namespace "ns:yang";
-
- prefix "yng";
- revision 2013-11-26 {
- }
-
- container cont {
- leaf lf1 {
- type string;
- }
- leaf lf2 {
- type string;
- }
- container cont1{
- leaf lf11 {
- type string;
- }
- }
-
- list lst1{
- leaf lf11 {
- type string;
- }
- }
- leaf-list lflst1{
- type string;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-module choice-case-test {
- namespace "choice:case:test";
-
- prefix "chcatst";
- revision 2013-11-27 {
- }
-
- container cont {
- leaf lf1 {
- type string;
- }
-
- choice choi1 {
- case a1 {
- leaf lf1a {
- type uint16;
- }
- choice choi1a {
- case aa1 {
- leaf lf1aa {
- type string;
- }
- choice choi1aa {
- case aaa1 {
- leaf lf1aaa {
- type string;
- }
- }
- case aab1 {
- leaf lf1aab {
- type string;
- }
- }
- }
- }
- case ab1 {
- leaf lf1ab {
- type string;
- }
- }
- }
- }
- case b1 {
- list lst1b {
- leaf lf11b {
- type string;
- }
- }
- }
- case c1 {
- container cont1c {
- leaf lf11c {
- type string;
- }
- }
- }
- case d1 {
- leaf-list lflst1d {
- type string;
- }
- }
- leaf e1 {
- type uint32;
- }
- }
-
- choice choi2 {
- case a2 {
- leaf lf2a {
- type string;
- }
- }
- case b2 {
- leaf lf2b {
- type string;
- }
- }
- }
-
- choice choi4 {
- case a4 {
- list lst4a {
- choice choi4aa {
- case aa1 {
- leaf lf4aa {
- type string;
- }
- }
- case ab2 {
- leaf lf4ab {
- type int16;
- }
- }
- }
- }
- }
- case b4 {
- leaf-list lflst4b {
- type uint32;
- }
- }
-
- }
-
-/* equal identifiers in various cases are illegal 7.9.2 rfc6020 */
-/*
- choice choi3 {
- case 3a {
- leaf lf3a {
- type string;
- }
- }
- case 3b {
- leaf lf3b {
- type string;
- }
- }
- }
-*/
-
- }
-
-
-
-}
\ No newline at end of file
+++ /dev/null
-<cont xmlns="choice:case:test">
- <e1>45</e1>
- <lf2b>lf2b val</lf2b>
-</cont>
\ No newline at end of file
+++ /dev/null
-<cont xmlns="choice:case:test">
- <cont1c>
- <lf11c>lf11c val</lf11c>
- </cont1c>
-</cont>
\ No newline at end of file
+++ /dev/null
-<cont xmlns="choice:case:test">
- <lflst1d>lflst1d_1 val</lflst1d>
- <lflst1d>lflst1d_2 val</lflst1d>
-</cont>
\ No newline at end of file
+++ /dev/null
-<cont xmlns="choice:case:test">
- <lst1b>
- <lf11b>lf11b_1 val</lf11b>
- </lst1b>
- <lst1b>
- <lf11b>lf11b_2 val</lf11b>
- </lst1b>
-</cont>
\ No newline at end of file
+++ /dev/null
-<cont xmlns="choice:case:test">
- <cont1c>
- <lf11c>lf11c val</lf11c>
- </cont1c>
- <lf2b>lf2b value</lf2b>
-</cont>
\ No newline at end of file
+++ /dev/null
-<cont xmlns="choice:case:test">
- <cont1c>
- <lf11c>lf11c val</lf11c>
- </cont1c>
- <lf2b>lf2b value</lf2b>
- <lf2a>lf2b value</lf2a>
-</cont>
\ No newline at end of file
+++ /dev/null
-<cont xmlns="choice:case:test">
- <lf1>lf1 val</lf1>
- <lf1a>121</lf1a>
- <lf1ab>lf1ab val</lf1ab>
-</cont>
\ No newline at end of file
+++ /dev/null
-<cont xmlns="choice:case:test">
- <lf1aa>lf1aa val</lf1aa>
- <lf1>lf1 val</lf1>
- <lf1a>121</lf1a>
- <lf1aaa>lf1aaa val</lf1aaa>
-</cont>
\ No newline at end of file
+++ /dev/null
-<cont xmlns="choice:case:test">
- <lf1aaa>lf1aaa value</lf1aaa>
- <lf2b>lf2b value</lf2b>
- <lst4a>
- <lf4ab>33</lf4ab>
- </lst4a>
- <lst4a>
- <lf4ab>33</lf4ab>
- </lst4a>
- <lst4a>
- <lf4ab>37</lf4ab>
- </lst4a>
-</cont>
\ No newline at end of file
+++ /dev/null
-<cont xmlns="choice:case:test">
- <lf1aa>lf1aa val</lf1aa>
- <lf1>lf1 val</lf1>
- <lf1a>121</lf1a>
- <lf1ab>lf1ab value</lf1ab>
-</cont>
\ No newline at end of file
+++ /dev/null
-module module1 {
- namespace "module:one";
-
- prefix "m1";
- revision 2014-01-17 {
- }
-
- container cont_m1 {
- leaf lf1_m1 {
- type string;
- }
- uses confB_gr;
- }
-
- grouping confB_gr {
- container contB_m1 {
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-module module2 {
- namespace "module:two";
-
- prefix "m2";
- revision 2014-01-17 {
- }
-
- container cont_m2 {
- leaf lf1_m2 {
- type string;
- }
- uses confB_gr;
- }
-
- grouping confB_gr {
- container contB_m2 {
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-module identity-module {
- namespace "identity:module";
-
- prefix "idemod";
- revision 2013-12-02 {
- }
-
- identity iden {
- }
-}
+++ /dev/null
-module identityref-module {
- namespace "identityref:module";
-
- prefix "iderefmod";
-
- import identity-module {prefix idemo; revision-date 2013-12-02; }
-
- revision 2013-12-02 {
- }
-
- container cont {
- container cont1 {
- leaf lf1 {
- type identityref {
- base "idemo:iden";
- }
- }
- }
- }
-
-}
+++ /dev/null
-module invalid-top-level-element {
- namespace "invalid:top:level:element";
-
- prefix "intoleel";
- revision 2013-12-17 {
- }
-
-
- leaf lf {
- type string;
- }
-
-}
\ No newline at end of file
+++ /dev/null
-module cont-augment-module {
- namespace "cont:augment:module";
-
- prefix "cntaugmod";
-
- import main-module {prefix mamo; revision-date 2013-12-02;}
-
- revision 2013-12-02 {
-
- }
-
- augment "/mamo:cont" {
- leaf-list lflst1 {
- type leafref {
- path "../mamo:lf1";
- }
- }
-
- leaf lf4 {
- type leafref {
- path "../mamo:lf1";
- }
- }
-
- /* reference to not leaf element */
- leaf lf6 {
- type leafref {
- path "../lflst1";
- }
- }
-
- leaf lf7 {
- type leafref {
- path "../lf4";
- }
- }
- }
-
-}
+++ /dev/null
-module main-module {
- namespace "main:module";
-
- prefix "mainmod";
- revision 2013-12-02 {
- }
-
- container cont {
- leaf lf1 {
- /*
- *FIX ME
- * If is this leaf lf1 called from cont-augment-module.yang
- * from lf4, type that will be returned to the lf1 is string.
- * Than there are failing tests because of we have string,
- * do not number(uint32)
- */
-// type uint32;
- type string;
- }
-
- container cont1 {
- leaf lf11 {
- /*
- * FIX ME TOO WITH BAD PARSING
- */
-// type boolean;
- type string;
- }
- }
-
- leaf lf2 {
- type leafref {
- path "../lf1";
- }
- }
-
- leaf lf3 {
- type leafref {
- path "/cont/cont1/lf11";
- }
- }
-
- /* reference to nonexisting leaf */
- leaf lf5 {
- type leafref {
- path "/cont/lf";
- }
- }
- }
-}
+++ /dev/null
-<cont xmlns="main:module"
- xmlns:cont-augment-module="cont:augment:module">
- <cont1>
- <lf11>true</lf11>
- </cont1>
- <lf3>true</lf3>
-</cont>
\ No newline at end of file
+++ /dev/null
-<cont xmlns="main:module"
- xmlns:cont-augment-module="cont:augment:module">
- <cont-augment-module:lf7>200</cont-augment-module:lf7>
-</cont>
\ No newline at end of file
+++ /dev/null
-<cont xmlns="main:module"
- xmlns:cont-augment-module="cont:augment:module">
- <lf5>137</lf5>
-</cont>
\ No newline at end of file
+++ /dev/null
-<cont xmlns="main:module"
- xmlns:cont-augment-module="cont:augment:module">
- <cont-augment-module:lf6>44</cont-augment-module:lf6>
-</cont>
\ No newline at end of file
+++ /dev/null
-<cont xmlns="main:module"
- xmlns:cont-augment-module="cont:augment:module">
- <cont-augment-module:lflst1>345</cont-augment-module:lflst1>
- <cont-augment-module:lflst1>346</cont-augment-module:lflst1>
- <cont-augment-module:lflst1>347</cont-augment-module:lflst1>
-</cont>
\ No newline at end of file
+++ /dev/null
-<cont xmlns="main:module"
- xmlns:cont-augment-module="cont:augment:module">
- <lf1>121</lf1>
- <lf2>121</lf2>
-</cont>
\ No newline at end of file
+++ /dev/null
-module simple-data-types {
- namespace "simple:data:types";
-
- prefix "smpdtp";
- revision 2013-11-12 {
- }
-
- identity iden {
- }
-
- typedef tpdfempty {
- type empty;
- }
-
- typedef tpdfbit {
- type bits {
- bit b1;
- bit b2;
- bit b3;
- }
- }
-
- typedef tpdfun4 {
- type boolean;
- }
-
- typedef tpdfun3 {
- type union {
- type tpdfbit;
- type tpdfempty;
- }
- }
-
- typedef tpdfun2 {
- type union {
- type tpdfun3;
- type tpdfun4;
- }
- }
-
- typedef tpdfun1 {
- type union {
- type uint8;
- type decimal64 {
- fraction-digits 2;
- }
- }
- }
-
- container cont {
- leaf lfnint8Min {
- type int8;
- }
- leaf lfnint8Max {
- type int8;
- }
- leaf lfnint16Min {
- type int16;
- }
- leaf lfnint16Max {
- type int16;
- }
- leaf lfnint32Min {
- type int32;
- }
- leaf lfnint32Max {
- type int32;
- }
- leaf lfnint64Min {
- type int64;
- }
- leaf lfnint64Max {
- type int64;
- }
-
- leaf lfnuint8Max {
- type uint8;
- }
- leaf lfnuint16Max {
- type uint16;
- }
- leaf lfnuint32Max {
- type uint32;
- }
- leaf lfuint64Max {
- type uint64;
- }
- leaf lfstr {
- type string;
- }
- leaf lfstr1 {
- type string;
- }
- leaf lfbool1 {
- type boolean;
- }
- leaf lfbool2 {
- type boolean;
- }
- leaf lfbool3 {
- type boolean;
- }
- leaf lfdecimal1 {
- type decimal64 {
- fraction-digits 2;
- }
- }
- leaf lfdecimal2 {
- type decimal64 {
- fraction-digits 2;
- }
- }
- leaf lfdecimal3 {
- type decimal64 {
- fraction-digits 2;
- }
- }
-
- leaf lfdecimal4 {
- type decimal64 {
- fraction-digits 2;
- }
- }
-
-
- leaf lfdecimal6 {
- type decimal64 {
- fraction-digits 2;
- }
- }
-
- leaf lfenum {
- type enumeration {
- enum enum1;
- enum enum2;
- enum enum3;
- enum enum4;
- }
- }
-
- leaf lfbits {
- type bits {
- bit bit1;
- bit bit2;
- bit bit3;
- bit bit4;
- }
- }
-
- leaf lfbinary {
- type binary;
- }
-
- leaf lfref1 { //reference to string type
- type leafref {
- path "../lfstr";
- }
- }
-
- leaf lfref2 { //reference to number type
- type leafref {
- path "../lfnint8Max";
- }
- }
-
- leaf lfempty {
- type empty;
- }
-
- leaf lfunion1 {
- type union {
- type uint16;
- type string;
- }
- }
- leaf lfunion2 {
- type union {
- type decimal64 {
- fraction-digits 2;
- }
- type string;
- }
- }
-
- leaf lfunion3 {
- type union {
- type empty;
- type string;
- }
- }
-
- leaf lfunion4 {
- type union {
- type boolean;
- type string;
- }
- }
-
- leaf lfunion5 {
- type union {
- type uint16;
- type string;
- }
- }
-
- leaf lfunion6 {
- type union {
- type uint16;
- type empty;
- }
- }
-
- leaf lfunion7 {
- type tpdfun3;
- }
-
- leaf lfunion8 {
- type union {
- type uint16;
- type string;
- }
- }
-
- leaf lfunion9 {
- type union {
- type uint16;
- type boolean;
- }
- }
-
- leaf lfunion10 {
- type union {
- type bits {
- bit bt1;
- bit bt2;
- }
- type boolean;
- }
- }
-
- leaf lfunion11 {
- type union {
- type tpdfun1;
- type tpdfun2;
- }
- }
-
- leaf lfunion12 {
- type tpdfun2;
- }
-
- leaf lfunion13 {
- type tpdfbit;
- }
-
- leaf lfunion14 {
- type union {
- type enumeration {
- enum zero;
- enum one;
- }
- type uint16;
- }
- }
-
- leaf identityref1 {
- type identityref {
- base iden;
- }
- }
-
-
- }
-}
\ No newline at end of file
+++ /dev/null
-module simple-data-types {
- namespace "simple:data:types";
-
- prefix "smpdtp";
- revision 2013-11-12 {
- }
-
- identity iden {
- }
-
- typedef tpdfempty {
- type empty;
- }
-
- typedef tpdfbit {
- type bits {
- bit b1;
- bit b2;
- bit b3;
- }
- }
-
- typedef tpdfun4 {
- type boolean;
- }
-
- typedef tpdfun3 {
- type union {
- type tpdfbit;
- type tpdfempty;
- }
- }
-
- typedef tpdfun2 {
- type union {
- type tpdfun3;
- type tpdfun4;
- }
- }
-
- typedef tpdfun1 {
- type union {
- type uint8;
- type decimal64 {
- fraction-digits 2;
- }
- }
- }
-
- container cont {
- leaf lfnint8Min {
- type int8;
- }
- leaf lfnint8Max {
- type int8;
- }
- leaf lfnint16Min {
- type int16;
- }
- leaf lfnint16Max {
- type int16;
- }
- leaf lfnint32Min {
- type int32;
- }
- leaf lfnint32Max {
- type int32;
- }
- leaf lfnint64Min {
- type int64;
- }
- leaf lfnint64Max {
- type int64;
- }
-
- leaf lfnuint8Max {
- type uint8;
- }
- leaf lfnuint16Max {
- type uint16;
- }
- leaf lfnuint32Max {
- type uint32;
- }
- leaf lfuint64Max {
- type uint64;
- }
- leaf lfstr {
- type string;
- }
- leaf lfstr1 {
- type string;
- }
- leaf lfbool1 {
- type boolean;
- }
- leaf lfbool2 {
- type boolean;
- }
- leaf lfbool3 {
- type boolean;
- }
- leaf lfdecimal1 {
- type decimal64 {
- fraction-digits 2;
- }
- }
- leaf lfdecimal2 {
- type decimal64 {
- fraction-digits 2;
- }
- }
- leaf lfdecimal3 {
- type decimal64 {
- fraction-digits 2;
- }
- }
-
- leaf lfdecimal4 {
- type decimal64 {
- fraction-digits 2;
- }
- }
-
-
- leaf lfdecimal6 {
- type decimal64 {
- fraction-digits 2;
- }
- }
-
- leaf lfenum {
- type enumeration {
- enum enum1;
- enum enum2;
- enum enum3;
- enum enum4;
- }
- }
-
- leaf lfbits {
- type bits {
- bit bit1;
- bit bit2;
- bit bit3;
- bit bit4;
- }
- }
-
- leaf lfbinary {
- type binary;
- }
-
- leaf lfref1 { //reference to string type
- type leafref {
- path "../lfstr";
- }
- }
-
- leaf lfref2 { //reference to number type
- type leafref {
- path "../lfnint8Max";
- }
- }
-
- leaf lfempty {
- type empty;
- }
-
- leaf lfunion1 {
- type union {
- type uint16;
- type string;
- }
- }
- leaf lfunion2 {
- type union {
- type decimal64 {
- fraction-digits 2;
- }
- type string;
- }
- }
-
- leaf lfunion3 {
- type union {
- type empty;
- type string;
- }
- }
-
- leaf lfunion4 {
- type union {
- type boolean;
- type string;
- }
- }
-
- leaf lfunion5 {
- type union {
- type uint16;
- type string;
- }
- }
-
- leaf lfunion6 {
- type union {
- type uint16;
- type empty;
- }
- }
-
- leaf lfunion7 {
- type tpdfun3;
- }
-
- leaf lfunion8 {
- type union {
- type uint16;
- type string;
- }
- }
-
- leaf lfunion9 {
- type union {
- type uint16;
- type boolean;
- }
- }
-
- leaf lfunion10 {
- type union {
- type bits {
- bit bt1;
- bit bt2;
- }
- type boolean;
- }
- }
-
- leaf lfunion11 {
- type union {
- type tpdfun1;
- type tpdfun2;
- }
- }
-
- leaf lfunion12 {
- type tpdfun2;
- }
-
- leaf lfunion13 {
- type tpdfbit;
- }
-
- leaf lfunion14 {
- type union {
- type enumeration {
- enum zero;
- enum one;
- }
- type uint16;
- }
- }
-
- leaf identityref1 {
- type identityref {
- base iden;
- }
- }
-
- anyxml complex-any;
-
- anyxml simple-any;
-
- anyxml empty-any;
- }
-}
\ No newline at end of file
+++ /dev/null
-<cont xmlns= "simple:data:types">
- <lfnint8Min>invalid</lfnint8Min>
-</cont>
\ No newline at end of file
+++ /dev/null
-<cont xmlns="simple:data:types">
- <lfnint8Min>-128</lfnint8Min>
- <lfnint8Max>127</lfnint8Max>
- <lfnint16Min>-32768</lfnint16Min>
- <lfnint16Max>32767</lfnint16Max>
- <lfnint32Min>-2147483648</lfnint32Min>
- <lfnint32Max>2147483647</lfnint32Max>
- <lfnint64Min>-9223372036854775808</lfnint64Min>
- <lfnint64Max>9223372036854775807</lfnint64Max>
- <lfnuint8Max>255</lfnuint8Max>
- <lfnuint16Max>65535</lfnuint16Max>
- <lfnuint32Max>4294967295</lfnuint32Max>
- <lfstr>lfstr</lfstr>
- <lfstr1></lfstr1>
- <lfbool1>true</lfbool1>
- <lfbool2>false</lfbool2>
- <lfbool3>bla</lfbool3>
- <lfdecimal1>43.32</lfdecimal1>
- <lfdecimal2>-0.43</lfdecimal2>
- <lfdecimal3>43</lfdecimal3>
- <lfdecimal4>43E3</lfdecimal4>
- <lfdecimal6>33.12345</lfdecimal6>
- <lfenum>enum3</lfenum>
- <lfbits>bit3 bit2</lfbits>
- <lfbinary>ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz</lfbinary>
- <lfunion1>324</lfunion1>
- <lfunion2>33.3</lfunion2>
- <lfunion3>55</lfunion3>
- <lfunion4>true</lfunion4>
- <lfunion5>true</lfunion5>
- <lfunion6>10</lfunion6>
- <lfunion7></lfunion7>
- <lfunion8></lfunion8>
- <lfunion9></lfunion9>
- <lfunion10>bt1</lfunion10>
- <lfunion11>33</lfunion11>
- <lfunion12>false</lfunion12>
- <lfunion13>b1</lfunion13>
- <lfunion14>zero</lfunion14>
- <lfempty></lfempty>
- <identityref1 xmlns:x="simple:data:types">x:iden</identityref1>
- <complex-any>
- <data>
- <leaf1>leaf1-value</leaf1>
- <leaf2>leaf2-value</leaf2>
-
- <leaf-list>leaf-list-value1</leaf-list>
- <leaf-list>leaf-list-value2</leaf-list>
-
- <list>
- <nested-list>
- <nested-leaf>nested-value1</nested-leaf>
- </nested-list>
- <nested-list>
- <nested-leaf>nested-value2</nested-leaf>
- </nested-list>
- </list>
-
- <list>
- <nested-list>
- <nested-leaf>nested-value3</nested-leaf>
- </nested-list>
- <nested-list>
- <nested-leaf>nested-value4</nested-leaf>
- </nested-list>
- </list>
- </data>
- </complex-any>
- <simple-any>simple</simple-any>
- <empty-any></empty-any>
-</cont>
+++ /dev/null
-module simple-yang-types {
- namespace "simple:yang:types";
-
- prefix "smptp";
- revision 2013-11-5 {
- description "Initial revision.";
- }
-
- container cont1 {
- leaf lf11 {
- type string;
- }
- leaf-list lflst11 {
- type int32;
- }
- leaf-list lflst12 {
- type string;
- }
- list lst11 {
- key "lf111";
- leaf lf111 {
- type uint8;
- }
- leaf lf112 {
- type string;
- }
- container cont111 {
- leaf lf1111 {
- type string;
- }
- leaf-list lflst1111 {
- type int32;
- }
- list lst1111 {
- leaf lf1111A {
- type string;
- }
- leaf lf1111B {
- type uint8;
- }
- }
- }
- list lst111 {
- leaf lf1111 {
- type int32;
- }
- }
- list lst112 {
- leaf lf1121 {
- type string;
- }
- }
- }
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-{
- "cont1": {
- "lf11":"lf",
- "lflst11": [55,56,57],
- "lflst12": ["lflst12 str1", "lflst12 str2", "lflst12 str3"],
- "lst11": [
- {
- "lf111":140,
- "lf112":"lf112 str",
- "cont111": {
- "lf1111":"lf1111 str",
- "lflst1111": [2048, 1024, 4096],
- "lst1111": [
- {
- "lf1111A": "lf1111A str11",
- "lf1111B": 4
- },
- {
- "lf1111A": "lf1111A str12",
- "lf1111B": 7
- }
- ]
- },
- "lst111" : [
- {
- "lf1111" : 65
- }
- ],
- "lst112" : [
- {
- "lf1121" : "lf1121 str11"
- }
- ]
-
- },
- {
- "lf111":141,
- "lf112":"lf112 str2",
- "cont111": {
- "lf1111":"lf1111 str2",
- "lflst1111": [2049, 1025, 4097],
- "lst1111": [
- {
- "lf1111A": "lf1111A str21",
- "lf1111B": 5
- },
- {
- "lf1111A": "lf1111A str22",
- "lf1111B": 8
- }
- ]
- },
- "lst111" : [
- {
- "lf1111" : 55
- },
- {
- "lf1111" : 56
- }
- ],
- "lst112" : [
- {
- "lf1121" : "lf1121 str21"
- },
- {
- "lf1121" : "lf1121 str22"
- }
- ]
- }
- ]
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "cont1": {
- "lst11": [
- {
- "lf111": 1,
- "lst111": [
- {
- "lf1111": 34
- },
- {
- "lf1111": 35
- },
- {},
- {}
- ],
- "cont111": {}
- },
- {
- "lf111": 2,
- "cont111": {
- "lflst1111": [
- 1024,
- 4096
- ],
- "lst1111": [
- {
- "lf1111B": 4
- },
- {
- "lf1111A": "lf1111A str12"
- }
- ]
- },
- "lst112": [
- {}
- ]
- },
- {
- "lf111": 3,
- "cont111": {
- "lst1111": [
- {},
- {}
- ]
- }
- }
- ]
- }
-}
\ No newline at end of file
+++ /dev/null
-<cont1 xmlns="simple:yang:types">
- <lf11>lf</lf11>
- <lflst11>56</lflst11>
- <lflst11>55</lflst11>
- <lflst11>57</lflst11>
- <lflst12>lflst12 str3</lflst12>
- <lst11>
- <lst112>
- <lf1121>lf1121 str22</lf1121>
- </lst112>
- <lf111>141</lf111>
- <lf112>lf112 str2</lf112>
- <lst111>
- <lf1111>55</lf1111>
- </lst111>
- <cont111>
- <lflst1111>4097</lflst1111>
- <lflst1111>2049</lflst1111>
- <lflst1111>1025</lflst1111>
- <lst1111>
- <lf1111A>lf1111A str22</lf1111A>
- <lf1111B>8</lf1111B>
- </lst1111>
- <lf1111>lf1111 str2</lf1111>
- <lst1111>
- <lf1111B>5</lf1111B>
- <lf1111A>lf1111A str21</lf1111A>
- </lst1111>
- </cont111>
- <lst111>
- <lf1111>56</lf1111>
- </lst111>
- <lst112>
- <lf1121>lf1121 str21</lf1121>
- </lst112>
- </lst11>
- <lflst12>lflst12 str1</lflst12>
- <lst11>
- <lf111>140</lf111>
- <lf112>lf112 str</lf112>
- <cont111>
- <lf1111>lf1111 str</lf1111>
- <lflst1111>2048</lflst1111>
- <lflst1111>1024</lflst1111>
- <lflst1111>4096</lflst1111>
- <lst1111>
- <lf1111A>lf1111A str11</lf1111A>
- <lf1111B>4</lf1111B>
- </lst1111>
- <lst1111>
- <lf1111A>lf1111A str12</lf1111A>
- <lf1111B>7</lf1111B>
- </lst1111>
- </cont111>
- <lst111>
- <lf1111>65</lf1111>
- </lst111>
- <lst112>
- <lf1121>lf1121 str11</lf1121>
- </lst112>
- </lst11>
- <lflst12>lflst12 str2</lflst12>
-</cont1>
+++ /dev/null
-<cont1>
- <lst11>
- <lf111>1</lf111>
- <lst111></lst111>
- <lst111></lst111>
- <lst111>
- <lf1111></lf1111>
- </lst111>
- <lst111>
- <lf1111>35</lf1111>
- </lst111>
- <cont111></cont111>
- </lst11>
- <lst11>
- <lf111>2</lf111>
- <cont111>
- <lf1111></lf1111>
- <lflst1111></lflst1111>
- <lflst1111>1024</lflst1111>
- <lflst1111>4096</lflst1111>
- <lst1111>
- <lf1111B>4</lf1111B>
- </lst1111>
- <lst1111>
- <lf1111A>lf1111A str12</lf1111A>
- </lst1111>
- </cont111>
- <lst112></lst112>
- </lst11>
- <lst11>
- <lf111>3</lf111>
- <cont111>
- <lf1111></lf1111>
- <lflst1111></lflst1111>
- <lflst1111></lflst1111>
- <lst1111></lst1111>
- <lst1111></lst1111>
- </cont111>
- </lst11>
-</cont1>
+++ /dev/null
-module module-with-choice {
- namespace "module:with:choice";
-
- prefix "mowicho";
-
- revision 2013-12-18 {
- }
-
-
- container cont {
- choice choA {
- case caA1 {
- leaf lf1 {
- type string;
- }
- }
- case caA2 {
- leaf lf2 {
- type string;
- }
- }
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-module module1 {
- namespace "module:one";
-
- prefix "m1";
- revision 2014-01-17 {
- }
-
- container cont_m1 {
- leaf lf1_m1 {
- type string;
- }
- uses confB_gr;
- }
-
- grouping confB_gr {
- container contB_m1 {
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-module module2 {
- namespace "module:two";
-
- prefix "m2";
- revision 2014-01-17 {
- }
-
- container cont_m2 {
- leaf lf1_m2 {
- type string;
- }
- uses confB_gr;
- }
-
- grouping confB_gr {
- container contB_m2 {
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-module aug-referenced-elements-module {
- namespace "aug:referenced:elements:module";
-
- prefix "augrefelmo";
-
- import referenced-elements-module {prefix refelmo; revision-date 2013-12-03;}
-
- revision 2013-12-03 {
- }
-
- augment "/refelmo:cont" {
- leaf lf2 {
- type boolean;
- }
- }
-
-
-}
+++ /dev/null
-module referenced-elements-module {
- namespace "referenced:elements:module";
-
- prefix "refelmo";
-
- revision 2013-12-03 {
- }
-
- container cont {
- leaf lf1 {
- type string;
- }
- }
- leaf-list lflst1 {
- type uint32;
- }
-
- }
-
-}
+++ /dev/null
-module instance-identifier-module {
- namespace "instance:identifier:module";
-
- prefix "inidmod";
-
- revision 2013-12-03 {
- }
-
- container cont {
- leaf lf1 {
- type instance-identifier {
- }
- }
- }
-
-}
+++ /dev/null
-module basic-module {
- namespace "basic:module";
-
- prefix "basmod";
-
- import referenced-module {prefix refmo; revision-date 2013-12-02;}
-
- revision 2013-12-02 {
- }
-
- container cont {
- container cont1 {
- leaf lf11 {
- type identityref {
- base "refmo:iden";
- }
- }
- }
- leaf lfStr {
- type string;
- }
- leaf lfInt8 {
- type int8;
- }
-
- leaf lfInt16 {
- type int16;
- }
-
- leaf lfInt32 {
- type int32;
- }
-
- leaf lfInt64 {
- type int64;
- }
-
- leaf lfUint8 {
- type uint8;
- }
-
- leaf lfUint16 {
- type uint16;
- }
-
- leaf lfUint32 {
- type uint32;
- }
-
- leaf lfUint64 {
- type uint64;
- }
-
- leaf lfBinary {
- type binary;
- }
-
- leaf lfBits {
- type bits {
- bit one;
- bit two;
- bit three;
- }
- }
-
- leaf lfEnumeration {
- type enumeration {
- enum enum1;
- enum enum2;
- enum enum3;
- }
- }
-
- leaf lfEmpty {
- type empty;
- }
-
- leaf lfBoolean {
- type boolean;
- }
-
- leaf lfUnion {
- type union {
- type int8;
- type string;
- type bits {
- bit first;
- bit second;
- }
- type boolean;
- }
- }
-
- leaf lfLfref {
- type leafref {
- path "/cont/lfBoolean";
- }
- }
-
- leaf lfLfrefNegative {
- type leafref {
- path "/cont/not-existing";
- }
- }
-
- leaf lfInIdentifier {
- type instance-identifier;
- }
-
- }
-}
+++ /dev/null
-module referenced-module {
- namespace "referenced:module";
-
- prefix "refmod";
- revision 2013-12-02 {
- }
-
- identity iden {
- }
-}
+++ /dev/null
-module normalize-node-module {
- namespace "normalize:node:module";
-
- prefix "nonomo";
- revision 2014-01-09 {
- }
-
- container cont {
- leaf lf1 {
- type int32;
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
- 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)";
- }
-
- }
+++ /dev/null
-module ietf-restconf-monitoring {
- namespace "urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring";
- prefix "rcmon";
-
- import ietf-yang-types { prefix yang; }
- import ietf-inet-types { prefix inet; }
-
- organization
- "IETF NETCONF (Network Configuration) Working Group";
-
- contact
- "WG Web: <https://datatracker.ietf.org/wg/netconf/>
- WG List: <mailto:netconf@ietf.org>
-
- Author: Andy Bierman
- <mailto:andy@yumaworks.com>
-
- Author: Martin Bjorklund
- <mailto:mbj@tail-f.com>
-
- Author: Kent Watsen
- <mailto:kwatsen@juniper.net>";
-
- description
- "This module contains monitoring information for the
- RESTCONF protocol.
-
- Copyright (c) 2017 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 8040; see
- the RFC itself for full legal notices.";
-
- revision 2017-01-26 {
- description
- "Initial revision.";
- reference
- "RFC 8040: RESTCONF Protocol.";
- }
-
- container restconf-state {
- config false;
- description
- "Contains RESTCONF protocol monitoring information.";
-
- container capabilities {
- description
- "Contains a list of protocol capability URIs.";
-
- leaf-list capability {
- type inet:uri;
- description
- "A RESTCONF protocol capability URI.";
- }
- }
-
- container streams {
- description
- "Container representing the notification event streams
- supported by the server.";
- reference
- "RFC 5277, Section 3.4, <streams> element.";
-
- list stream {
- key name;
- description
- "Each entry describes an event stream supported by
- the server.";
-
- leaf name {
- type string;
- description
- "The stream name.";
- reference
- "RFC 5277, Section 3.4, <name> element.";
- }
-
- leaf description {
- type string;
- description
- "Description of stream content.";
- reference
- "RFC 5277, Section 3.4, <description> element.";
- }
-
- leaf replay-support {
- type boolean;
- default false;
- description
- "Indicates if replay buffer is supported for this stream.
- If 'true', then the server MUST support the 'start-time'
- and 'stop-time' query parameters for this stream.";
- reference
- "RFC 5277, Section 3.4, <replaySupport> element.";
- }
-
- leaf replay-log-creation-time {
- when "../replay-support" {
- description
- "Only present if notification replay is supported.";
- }
- type yang:date-and-time;
- description
- "Indicates the time the replay log for this stream
- was created.";
- reference
- "RFC 5277, Section 3.4, <replayLogCreationTime>
- element.";
- }
-
- list access {
- key encoding;
- min-elements 1;
- description
- "The server will create an entry in this list for each
- encoding format that is supported for this stream.
- The media type 'text/event-stream' is expected
- for all event streams. This list identifies the
- subtypes supported for this stream.";
-
- leaf encoding {
- type string;
- description
- "This is the secondary encoding format within the
- 'text/event-stream' encoding used by all streams.
- The type 'xml' is supported for XML encoding.
- The type 'json' is supported for JSON encoding.";
- }
-
- leaf location {
- type inet:uri;
- mandatory true;
- description
- "Contains a URL that represents the entry point
- for establishing notification delivery via
- server-sent events.";
- }
- }
- }
- }
- }
-}
+++ /dev/null
-module ietf-yang-library {
- namespace "urn:ietf:params:xml:ns:yang:ietf-yang-library";
- prefix "yanglib";
- import ietf-yang-types {
- prefix yang;
- }
- import ietf-inet-types {
- prefix inet;
- }
- organization
- "IETF NETCONF (Network Configuration) Working Group";
- contact
- "WG Web: <https://datatracker.ietf.org/wg/netconf/>
- WG List: <mailto:netconf@ietf.org>
- WG Chair: Mehmet Ersue
- <mailto:mehmet.ersue@nsn.com>
- WG Chair: Mahesh Jethanandani
- <mailto:mjethanandani@gmail.com>
- Editor: Andy Bierman
- <mailto:andy@yumaworks.com>
- Editor: Martin Bjorklund
- <mailto:mbj@tail-f.com>
- Editor: Kent Watsen
- <mailto:kwatsen@juniper.net>";
- description
- "This module contains monitoring information about the YANG
- modules and submodules that are used within a YANG-based
- server.
- Copyright (c) 2016 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 7895; see
- the RFC itself for full legal notices.";
- revision 2016-06-21 {
- description
- "Initial revision.";
- reference
- "RFC 7895: YANG Module Library.";
- }
- /*
- * Typedefs
- */
- typedef revision-identifier {
- type string {
- pattern '\d{4}-\d{2}-\d{2}';
- }
- description
- "Represents a specific date in YYYY-MM-DD format.";
- }
- /*
- * Groupings
- */
- grouping module-list {
- description
- "The module data structure is represented as a grouping
- so it can be reused in configuration or another monitoring
- data structure.";
- grouping common-leafs {
- description
- "Common parameters for YANG modules and submodules.";
- leaf name {
- type yang:yang-identifier;
- description
- "The YANG module or submodule name.";
- }
- leaf revision {
- type union {
- type revision-identifier;
- type string { length 0; }
- }
- description
- "The YANG module or submodule revision date.
- A zero-length string is used if no revision statement
- is present in the YANG module or submodule.";
- }
- }
- grouping schema-leaf {
- description
- "Common schema leaf parameter for modules and submodules.";
- leaf schema {
- type inet:uri;
- description
- "Contains a URL that represents the YANG schema
- resource for this module or submodule.
- This leaf will only be present if there is a URL
- available for retrieval of the schema for this entry.";
- }
- }
- list module {
- key "name revision";
- description
- "Each entry represents one revision of one module
- currently supported by the server.";
- uses common-leafs;
- uses schema-leaf;
- leaf namespace {
- type inet:uri;
- mandatory true;
- description
- "The XML namespace identifier for this module.";
- }
- leaf-list feature {
- type yang:yang-identifier;
- description
- "List of YANG feature names from this module that are
- supported by the server, regardless of whether they are
- defined in the module or any included submodule.";
- }
- list deviation {
- key "name revision";
- description
- "List of YANG deviation module names and revisions
- used by this server to modify the conformance of
- the module associated with this entry. Note that
- the same module can be used for deviations for
- multiple modules, so the same entry MAY appear
- within multiple 'module' entries.
- The deviation module MUST be present in the 'module'
- list, with the same name and revision values.
- The 'conformance-type' value will be 'implement' for
- the deviation module.";
- uses common-leafs;
- }
- leaf conformance-type {
- type enumeration {
- enum implement {
- description
- "Indicates that the server implements one or more
- protocol-accessible objects defined in the YANG module
- identified in this entry. This includes deviation
- statements defined in the module.
- For YANG version 1.1 modules, there is at most one
- module entry with conformance type 'implement' for a
- particular module name, since YANG 1.1 requires that,
- at most, one revision of a module is implemented.
- For YANG version 1 modules, there SHOULD NOT be more
- than one module entry for a particular module name.";
- }
- enum import {
- description
- "Indicates that the server imports reusable definitions
- from the specified revision of the module but does
- not implement any protocol-accessible objects from
- this revision.
- Multiple module entries for the same module name MAY
- exist. This can occur if multiple modules import the
- same module but specify different revision dates in
- the import statements.";
- }
- }
- mandatory true;
- description
- "Indicates the type of conformance the server is claiming
- for the YANG module identified by this entry.";
- }
- list submodule {
- key "name revision";
- description
- "Each entry represents one submodule within the
- parent module.";
- uses common-leafs;
- uses schema-leaf;
- }
- }
- }
- /*
- * Operational state data nodes
- */
- container modules-state {
- config false;
- description
- "Contains YANG module monitoring information.";
- leaf module-set-id {
- type string;
- mandatory true;
- description
- "Contains a server-specific identifier representing
- the current set of modules and submodules. The
- server MUST change the value of this leaf if the
- information represented by the 'module' list instances
- has changed.";
- }
- uses module-list;
- }
- /*
- * Notifications
- */
- notification yang-library-change {
- description
- "Generated when the set of modules and submodules supported
- by the server has changed.";
- leaf module-set-id {
- type leafref {
- path "/yanglib:modules-state/yanglib:module-set-id";
- }
- mandatory true;
- description
- "Contains the module-set-id value representing the
- set of modules and submodules supported at the server at
- the time the notification is generated.";
- }
- }
-}
+++ /dev/null
- 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)";
- }
-
- 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 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";
- }
-
- }
+++ /dev/null
-module notifi-module {
- namespace "notifi:mod";
- prefix notm;
-
- revision "2016-11-23" {
- }
-
- notification notifi-leaf {
- leaf lf {
- type string;
- }
- }
-
- notification notifi-cont {
- container cont {
- leaf lf {
- type string;
- }
- }
- }
-
- notification notifi-list {
- list lst {
- key lf;
- leaf lf {
- type string;
- }
- }
- }
-
- notification notifi-grp {
- uses grp;
- }
-
- grouping grp {
- leaf lf {
- type string;
- }
- }
-
- notification notifi-augm {
- }
-
- augment /notifi-augm {
- leaf lf-augm {
- type string;
- }
- }
-}
+++ /dev/null
-module subscribe-to-notification {
-
- yang-version 1;
- namespace "subscribe:to:notification";
- prefix "subs-to-notifi";
-
- description
- "Added input parameters to rpc create-data-change-event-subscription and to create-notification-stream";
-
- revision "2016-10-28" {
- }
-
- container "notifi"{
- leaf "location"{
- type string;
- }
- }
-}
+++ /dev/null
-module toaster {
-
- yang-version 1;
-
- namespace
- "http://netconfcentral.org/ns/toaster";
-
- prefix toast;
-
- organization "Netconf Central";
-
- contact
- "Andy Bierman <andy@netconfcentral.org>";
-
- description
- "YANG version of the TOASTER-MIB.";
-
- revision "2009-11-20" {
- description
- "Toaster module in progress.";
- }
-
-
- identity toast-type {
- description
- "Base for all bread types supported by the toaster.
- New bread types not listed here nay be added in the
- future.";
- }
-
- identity white-bread {
- base toast:toast-type;
- description "White bread.";
- }
-
- identity wheat-bread {
- base toast-type;
- description "Wheat bread.";
- }
-
- identity wonder-bread {
- base toast-type;
- description "Wonder bread.";
- }
-
- identity frozen-waffle {
- base toast-type;
- description "Frozen waffle.";
- }
-
- identity frozen-bagel {
- base toast-type;
- description "Frozen bagel.";
- }
-
- identity hash-brown {
- base toast-type;
- description "Hash browned potatos.";
- }
-
- typedef DisplayString {
- type string {
- length "0 .. 255";
- }
- description
- "YANG version of the SMIv2 DisplayString TEXTUAL-CONVENTION.";
- reference
- "RFC 2579, section 2.";
-
- }
-
- container toaster {
- presence
- "Indicates the toaster service is available";
- description
- "Top-level container for all toaster database objects.";
- leaf toasterManufacturer {
- type DisplayString;
- config false;
- mandatory true;
- description
- "The name of the toaster's manufacturer. For instance,
- Microsoft Toaster.";
- }
-
- leaf toasterModelNumber {
- type DisplayString;
- config false;
- mandatory true;
- description
- "The name of the toaster's model. For instance,
- Radiant Automatic.";
- }
-
- leaf toasterStatus {
- type enumeration {
- enum "up" {
- value 1;
- description
- "The toaster knob position is up.
- No toast is being made now.";
- }
- enum "down" {
- value 2;
- description
- "The toaster knob position is down.
- Toast is being made now.";
- }
- }
- config false;
- mandatory true;
- description
- "This variable indicates the current state of
- the toaster.";
- }
-
- leaf darknessFactor {
- type uint32;
- config true;
- default 1000;
- description
- "The darkness factor. Basically, the number of ms to multiple the doneness value by.";
- }
- } // container toaster
-
- rpc make-toast {
- description
- "Make some toast.
- The toastDone notification will be sent when
- the toast is finished.
- An 'in-use' error will be returned if toast
- is already being made.
- A 'resource-denied' error will be returned
- if the toaster service is disabled.";
- input {
- leaf toasterDoneness {
- type uint32 {
- range "1 .. 10";
- }
- default '5';
- description
- "This variable controls how well-done is the
- ensuing toast. It should be on a scale of 1 to 10.
- Toast made at 10 generally is considered unfit
- for human consumption; toast made at 1 is warmed
- lightly.";
- }
-
- leaf toasterToastType {
- type identityref {
- base toast:toast-type;
- }
- default 'wheat-bread';
- description
- "This variable informs the toaster of the type of
- material that is being toasted. The toaster
- uses this information, combined with
- toasterDoneness, to compute for how
- long the material must be toasted to achieve
- the required doneness.";
- }
- }
- } // rpc make-toast
-
- rpc cancel-toast {
- description
- "Stop making toast, if any is being made.
- A 'resource-denied' error will be returned
- if the toaster service is disabled.";
- } // rpc cancel-toast
-
- rpc restock-toaster {
- description
- "Restocks the toaster with the amount of bread specified.";
-
- input {
- leaf amountOfBreadToStock {
- type uint32;
- description
- "Indicates the amount of bread to re-stock";
- }
- }
- }
-
- notification toasterOutOfBread {
- description
- "Indicates that the toaster has run of out bread.";
- } // notification toasterOutOfStock
-
- notification toasterRestocked {
- description
- "Indicates that the toaster has run of out bread.";
- leaf amountOfBread {
- type uint32;
- description
- "Indicates the amount of bread that was re-stocked";
- }
- } // notification toasterOutOfStock
-
- } // module toaster
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
- <eventTime>2016-11-10T04:45:31+01:00</eventTime>
- <data-changed-notification xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote">
- <data-change-event>
- <path>/toaster:toaster/toaster:toasterStatus</path>
- <operation>updated</operation>
- <data>
- <toasterStatus xmlns="http://netconfcentral.org/ns/toaster">down</toasterStatus>
- </data>
- </data-change-event>
- </data-changed-notification>
-</notification>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
- <eventTime>2016-11-10T04:45:31+01:00</eventTime>
- <data-changed-notification xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote">
- <data-change-event>
- <path>/toaster:toaster/toaster:toasterStatus</path>
- <operation>updated</operation>
- <data>
- <toasterStatus xmlns="http://netconfcentral.org/ns/toaster">1</toasterStatus>
- </data>
- </data-change-event>
- </data-changed-notification>
-</notification>
\ No newline at end of file
+++ /dev/null
-module ordered-example {
- namespace "ordered:example";
- prefix "oex";
-
- revision 2016-11-13 {
- description
- "Initial revision.";
- }
-
- container cont {
- list playlist {
- key name;
-
- leaf name {
- type string;
- }
- list song {
- key index;
- ordered-by user;
-
- leaf index {
- type uint32;
- }
- leaf id {
- type instance-identifier;
- mandatory true;
- description
- "Song identifier. Must identify an instance of
- /songs-cont/songs/song-name.";
- }
- }
- }
- }
-
- container songs-cont{
- list songs{
- key song-name;
-
- leaf song-name{
- type string;
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-module invoke-rpc-module {
- namespace "invoke:rpc:module";
- prefix "inrpcmod";
- yang-version 1;
-
- revision 2017-05-23 {
- description "Initial revision.";
- }
-
- rpc rpc-test {
- input {
- container cont {
- leaf lf {
- type string;
- }
- }
- }
- output {
- container cont-out {
- leaf lf-out {
- type string;
- }
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-module mount-point {
- namespace "mount:point";
- prefix "mountp";
- yang-version 1;
-
- import parser-identifier-included { prefix pii; revision-date 2016-06-02; }
-
- revision 2016-06-02 {
- description "Initial revision.";
- }
-
- container mount-container {
- leaf point-number {
- type uint8;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-module parser-identifier-included {
- namespace "parser:identifier:included";
- prefix "parseridinc";
- yang-version 1;
-
- revision 2016-06-02 {
- description
- "Initial revision.";
- }
-
- list list-1 {
- key "name revision";
- description "List in grouping";
-
- leaf name {
- type string;
- }
-
- leaf revision {
- type string;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-module parser-identifier {
- namespace "parser:identifier";
- prefix "parserid";
- yang-version 1;
-
- import parser-identifier-included { prefix pii; revision-date 2016-06-02; }
-
- revision 2016-06-02 {
- description
- "Initial revision.";
- }
-
- container cont1 {
- container cont2 {
- list listTest {
- uses group;
- }
- }
- }
-
- grouping group {
- list list-in-grouping {
- key name;
-
- leaf name {
- type string;
- }
-
- leaf leaf-A.B {
- type uint8;
- }
- }
- }
-
- augment "/pii:list-1" {
- leaf augment-leaf {
- type string;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-module test-module {
- namespace "test:module";
- prefix "testm";
- yang-version 1;
-
- revision 2016-06-02 {
- description "Initial revision.";
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "interface":[
- {
- "name":"eth0",
- "type":"ethernetCsmacd",
- "enabled":false,
- "description": "some interface"
- }
- ]
-}
\ No newline at end of file
+++ /dev/null
-<interface xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
- <name>eth0</name>
- <type>ethernetCsmacd</type>
- <enabled>false</enabled>
- <description>some interface</description>
-</interface>
+++ /dev/null
-<class xmlns="test:module">
- <name>xxx</name>
- <address>bbb</address>
- <email>ccc</email>
-</class>
\ No newline at end of file
+++ /dev/null
-{
- "ietf-interfaces:interfaces":{
- "interface":[
- {
- "name":"eth0",
- "type":"ethernetCsmacd",
- "enabled":false,
- "description": "some interface"
- }
- ]
- }
-}
\ No newline at end of file
+++ /dev/null
-<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces" >
- <interface>
- <name>eth0</name>
- <type>ethernetCsmacd</type>
- <enabled>false</enabled>
- <description>some interface</description>
- </interface>
-</interfaces>
\ No newline at end of file
+++ /dev/null
-
-<interface xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
- <name>eth0</name>
- <type>ethernetCsmacd</type>
- <enabled>false</enabled>
- <description>some interface</description>
-</interface>
+++ /dev/null
-<interface xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
- <name>eth0</name>
- <type>ethernetCsmacd</type>
- <enabled>false</enabled>
- <description>some interface</description>
-</interface>
+++ /dev/null
-{
- "ietf-restconf:yang-patch" : {
- "patch-id" : "0",
- "edit" : [
- {
- "edit-id" : "edit1",
- "operation" : "create",
- "target" : "",
- "value" : {
- "interface":[
- {
- "name":"eth0",
- "type":"ethernetCsmacd",
- "enabled":"false",
- "description": "some interface"
- }
- ]
- }
- }
- ]
- }
-}
\ No newline at end of file
+++ /dev/null
- 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)";
- }
-
- }
+++ /dev/null
-module ietf-restconf-monitoring {
- namespace "urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring";
- prefix "rcmon";
-
- import ietf-yang-types { prefix yang; }
- import ietf-inet-types { prefix inet; }
-
- organization
- "IETF NETCONF (Network Configuration) Working Group";
-
- contact
- "WG Web: <https://datatracker.ietf.org/wg/netconf/>
- WG List: <mailto:netconf@ietf.org>
-
- Author: Andy Bierman
- <mailto:andy@yumaworks.com>
-
- Author: Martin Bjorklund
- <mailto:mbj@tail-f.com>
-
- Author: Kent Watsen
- <mailto:kwatsen@juniper.net>";
-
- description
- "This module contains monitoring information for the
- RESTCONF protocol.
-
- Copyright (c) 2017 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 8040; see
- the RFC itself for full legal notices.";
-
- revision 2017-01-26 {
- description
- "Initial revision.";
- reference
- "RFC 8040: RESTCONF Protocol.";
- }
-
- container restconf-state {
- config false;
- description
- "Contains RESTCONF protocol monitoring information.";
-
- container capabilities {
- description
- "Contains a list of protocol capability URIs.";
-
- leaf-list capability {
- type inet:uri;
- description
- "A RESTCONF protocol capability URI.";
- }
- }
-
- container streams {
- description
- "Container representing the notification event streams
- supported by the server.";
- reference
- "RFC 5277, Section 3.4, <streams> element.";
-
- list stream {
- key name;
- description
- "Each entry describes an event stream supported by
- the server.";
-
- leaf name {
- type string;
- description
- "The stream name.";
- reference
- "RFC 5277, Section 3.4, <name> element.";
- }
-
- leaf description {
- type string;
- description
- "Description of stream content.";
- reference
- "RFC 5277, Section 3.4, <description> element.";
- }
-
- leaf replay-support {
- type boolean;
- default false;
- description
- "Indicates if replay buffer is supported for this stream.
- If 'true', then the server MUST support the 'start-time'
- and 'stop-time' query parameters for this stream.";
- reference
- "RFC 5277, Section 3.4, <replaySupport> element.";
- }
-
- leaf replay-log-creation-time {
- when "../replay-support" {
- description
- "Only present if notification replay is supported.";
- }
- type yang:date-and-time;
- description
- "Indicates the time the replay log for this stream
- was created.";
- reference
- "RFC 5277, Section 3.4, <replayLogCreationTime>
- element.";
- }
-
- list access {
- key encoding;
- min-elements 1;
- description
- "The server will create an entry in this list for each
- encoding format that is supported for this stream.
- The media type 'text/event-stream' is expected
- for all event streams. This list identifies the
- subtypes supported for this stream.";
-
- leaf encoding {
- type string;
- description
- "This is the secondary encoding format within the
- 'text/event-stream' encoding used by all streams.
- The type 'xml' is supported for XML encoding.
- The type 'json' is supported for JSON encoding.";
- }
-
- leaf location {
- type inet:uri;
- mandatory true;
- description
- "Contains a URL that represents the entry point
- for establishing notification delivery via
- server-sent events.";
- }
- }
- }
- }
- }
-}
+++ /dev/null
-module ietf-restconf {
- yang-version 1.1;
- namespace "urn:ietf:params:xml:ns:yang:ietf-restconf";
- prefix "rc";
-
- organization
- "IETF NETCONF (Network Configuration) Working Group";
-
- contact
- "WG Web: <https://datatracker.ietf.org/wg/netconf/>
- WG List: <mailto:netconf@ietf.org>
-
- Author: Andy Bierman
- <mailto:andy@yumaworks.com>
-
- Author: Martin Bjorklund
- <mailto:mbj@tail-f.com>
-
- Author: Kent Watsen
- <mailto:kwatsen@juniper.net>";
-
- description
- "This module contains conceptual YANG specifications
- for basic RESTCONF media type definitions used in
- RESTCONF protocol messages.
-
- Note that the YANG definitions within this module do not
- represent configuration data of any kind.
- The 'restconf-media-type' YANG extension statement
- provides a normative syntax for XML and JSON
- message-encoding purposes.
-
- Copyright (c) 2017 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 8040; see
- the RFC itself for full legal notices.";
-
- revision 2017-01-26 {
- description
- "Initial revision.";
- reference
- "RFC 8040: RESTCONF Protocol.";
- }
-
- extension yang-data {
- argument name {
- yin-element true;
- }
- description
- "This extension is used to specify a YANG data template that
- represents conceptual data defined in YANG. It is
- intended to describe hierarchical data independent of
- protocol context or specific message-encoding format.
- Data definition statements within a yang-data extension
- specify the generic syntax for the specific YANG data
- template, whose name is the argument of the 'yang-data'
- extension statement.
-
- Note that this extension does not define a media type.
- A specification using this extension MUST specify the
- message-encoding rules, including the content media type.
-
- The mandatory 'name' parameter value identifies the YANG
- data template that is being defined. It contains the
- template name.
-
- This extension is ignored unless it appears as a top-level
- statement. It MUST contain data definition statements
- that result in exactly one container data node definition.
- An instance of a YANG data template can thus be translated
- into an XML instance document, whose top-level element
- corresponds to the top-level container.
-
- The module name and namespace values for the YANG module using
- the extension statement are assigned to instance document data
- conforming to the data definition statements within
- this extension.
-
- The substatements of this extension MUST follow the
- 'data-def-stmt' rule in the YANG ABNF.
-
- The XPath document root is the extension statement itself,
- such that the child nodes of the document root are
- represented by the data-def-stmt substatements within
- this extension. This conceptual document is the context
- for the following YANG statements:
-
- - must-stmt
- - when-stmt
- - path-stmt
- - min-elements-stmt
- - max-elements-stmt
- - mandatory-stmt
- - unique-stmt
- - ordered-by
- - instance-identifier data type
-
- The following data-def-stmt substatements are constrained
- when used within a 'yang-data' extension statement.
-
- - The list-stmt is not required to have a key-stmt defined.
- - The if-feature-stmt is ignored if present.
- - The config-stmt is ignored if present.
- - The available identity values for any 'identityref'
- leaf or leaf-list nodes are limited to the module
- containing this extension statement and the modules
- imported into that module.
- ";
- }
-
- rc:yang-data yang-errors {
- uses errors;
- }
-
- rc:yang-data yang-api {
- uses restconf;
- }
-
- grouping errors {
- description
- "A grouping that contains a YANG container
- representing the syntax and semantics of a
- YANG Patch error report within a response message.";
-
- container errors {
- description
- "Represents an error report returned by the server if
- a request results in an error.";
-
- list error {
- description
- "An entry containing information about one
- specific error that occurred while processing
- a RESTCONF request.";
- reference
- "RFC 6241, Section 4.3.";
-
- leaf error-type {
- type enumeration {
- enum transport {
- description
- "The transport layer.";
- }
- enum rpc {
- description
- "The rpc or notification layer.";
- }
- enum protocol {
- description
- "The protocol operation layer.";
- }
- enum application {
- description
- "The server application layer.";
- }
- }
- mandatory true;
- description
- "The protocol layer where the error occurred.";
- }
-
- leaf error-tag {
- type string;
- mandatory true;
- description
- "The enumerated error-tag.";
- }
-
- leaf error-app-tag {
- type string;
- description
- "The application-specific error-tag.";
- }
-
- leaf error-path {
- type instance-identifier;
- description
- "The YANG instance identifier associated
- with the error node.";
- }
-
- leaf error-message {
- type string;
- description
- "A message describing the error.";
- }
-
- anydata error-info {
- description
- "This anydata value MUST represent a container with
- zero or more data nodes representing additional
- error information.";
- }
- }
- }
- }
-
- grouping restconf {
- description
- "Conceptual grouping representing the RESTCONF
- root resource.";
-
- container restconf {
- description
- "Conceptual container representing the RESTCONF
- root resource.";
-
- container data {
- description
- "Container representing the datastore resource.
- Represents the conceptual root of all state data
- and configuration data supported by the server.
- The child nodes of this container can be any data
- resources that are defined as top-level data nodes
- from the YANG modules advertised by the server in
- the 'ietf-yang-library' module.";
- }
-
- container operations {
- description
- "Container for all operation resources.
-
- Each resource is represented as an empty leaf with the
- name of the RPC operation from the YANG 'rpc' statement.
-
- For example, the 'system-restart' RPC operation defined
- in the 'ietf-system' module would be represented as
- an empty leaf in the 'ietf-system' namespace. This is
- a conceptual leaf and will not actually be found in
- the module:
-
- module ietf-system {
- leaf system-reset {
- type empty;
- }
- }
-
- To invoke the 'system-restart' RPC operation:
-
- POST /restconf/operations/ietf-system:system-restart
-
- To discover the RPC operations supported by the server:
-
- GET /restconf/operations
-
- In XML, the YANG module namespace identifies the module:
-
- <system-restart
- xmlns='urn:ietf:params:xml:ns:yang:ietf-system'/>
-
- In JSON, the YANG module name identifies the module:
-
- { 'ietf-system:system-restart' : [null] }
- ";
- }
-
- leaf yang-library-version {
- type string {
- pattern '\d{4}-\d{2}-\d{2}';
- }
- config false;
- mandatory true;
- description
- "Identifies the revision date of the 'ietf-yang-library'
- module that is implemented by this RESTCONF server.
- Indicates the year, month, and day in YYYY-MM-DD
- numeric format.";
- }
- }
- }
-}
+++ /dev/null
-module ietf-yang-library {
- namespace "urn:ietf:params:xml:ns:yang:ietf-yang-library";
- prefix "yanglib";
- import ietf-yang-types {
- prefix yang;
- }
- import ietf-inet-types {
- prefix inet;
- }
- organization
- "IETF NETCONF (Network Configuration) Working Group";
- contact
- "WG Web: <https://datatracker.ietf.org/wg/netconf/>
- WG List: <mailto:netconf@ietf.org>
- WG Chair: Mehmet Ersue
- <mailto:mehmet.ersue@nsn.com>
- WG Chair: Mahesh Jethanandani
- <mailto:mjethanandani@gmail.com>
- Editor: Andy Bierman
- <mailto:andy@yumaworks.com>
- Editor: Martin Bjorklund
- <mailto:mbj@tail-f.com>
- Editor: Kent Watsen
- <mailto:kwatsen@juniper.net>";
- description
- "This module contains monitoring information about the YANG
- modules and submodules that are used within a YANG-based
- server.
- Copyright (c) 2016 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 7895; see
- the RFC itself for full legal notices.";
- revision 2016-06-21 {
- description
- "Initial revision.";
- reference
- "RFC 7895: YANG Module Library.";
- }
- /*
- * Typedefs
- */
- typedef revision-identifier {
- type string {
- pattern '\d{4}-\d{2}-\d{2}';
- }
- description
- "Represents a specific date in YYYY-MM-DD format.";
- }
- /*
- * Groupings
- */
- grouping module-list {
- description
- "The module data structure is represented as a grouping
- so it can be reused in configuration or another monitoring
- data structure.";
- grouping common-leafs {
- description
- "Common parameters for YANG modules and submodules.";
- leaf name {
- type yang:yang-identifier;
- description
- "The YANG module or submodule name.";
- }
- leaf revision {
- type union {
- type revision-identifier;
- type string { length 0; }
- }
- description
- "The YANG module or submodule revision date.
- A zero-length string is used if no revision statement
- is present in the YANG module or submodule.";
- }
- }
- grouping schema-leaf {
- description
- "Common schema leaf parameter for modules and submodules.";
- leaf schema {
- type inet:uri;
- description
- "Contains a URL that represents the YANG schema
- resource for this module or submodule.
- This leaf will only be present if there is a URL
- available for retrieval of the schema for this entry.";
- }
- }
- list module {
- key "name revision";
- description
- "Each entry represents one revision of one module
- currently supported by the server.";
- uses common-leafs;
- uses schema-leaf;
- leaf namespace {
- type inet:uri;
- mandatory true;
- description
- "The XML namespace identifier for this module.";
- }
- leaf-list feature {
- type yang:yang-identifier;
- description
- "List of YANG feature names from this module that are
- supported by the server, regardless of whether they are
- defined in the module or any included submodule.";
- }
- list deviation {
- key "name revision";
- description
- "List of YANG deviation module names and revisions
- used by this server to modify the conformance of
- the module associated with this entry. Note that
- the same module can be used for deviations for
- multiple modules, so the same entry MAY appear
- within multiple 'module' entries.
- The deviation module MUST be present in the 'module'
- list, with the same name and revision values.
- The 'conformance-type' value will be 'implement' for
- the deviation module.";
- uses common-leafs;
- }
- leaf conformance-type {
- type enumeration {
- enum implement {
- description
- "Indicates that the server implements one or more
- protocol-accessible objects defined in the YANG module
- identified in this entry. This includes deviation
- statements defined in the module.
- For YANG version 1.1 modules, there is at most one
- module entry with conformance type 'implement' for a
- particular module name, since YANG 1.1 requires that,
- at most, one revision of a module is implemented.
- For YANG version 1 modules, there SHOULD NOT be more
- than one module entry for a particular module name.";
- }
- enum import {
- description
- "Indicates that the server imports reusable definitions
- from the specified revision of the module but does
- not implement any protocol-accessible objects from
- this revision.
- Multiple module entries for the same module name MAY
- exist. This can occur if multiple modules import the
- same module but specify different revision dates in
- the import statements.";
- }
- }
- mandatory true;
- description
- "Indicates the type of conformance the server is claiming
- for the YANG module identified by this entry.";
- }
- list submodule {
- key "name revision";
- description
- "Each entry represents one submodule within the
- parent module.";
- uses common-leafs;
- uses schema-leaf;
- }
- }
- }
- /*
- * Operational state data nodes
- */
- container modules-state {
- config false;
- description
- "Contains YANG module monitoring information.";
- leaf module-set-id {
- type string;
- mandatory true;
- description
- "Contains a server-specific identifier representing
- the current set of modules and submodules. The
- server MUST change the value of this leaf if the
- information represented by the 'module' list instances
- has changed.";
- }
- uses module-list;
- }
- /*
- * Notifications
- */
- notification yang-library-change {
- description
- "Generated when the set of modules and submodules supported
- by the server has changed.";
- leaf module-set-id {
- type leafref {
- path "/yanglib:modules-state/yanglib:module-set-id";
- }
- mandatory true;
- description
- "Contains the module-set-id value representing the
- set of modules and submodules supported at the server at
- the time the notification is generated.";
- }
- }
-}
+++ /dev/null
- 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)";
- }
-
- 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 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";
- }
-
- }
+++ /dev/null
-module deserializer-test-included {
- namespace "deserializer:test:included";
- prefix "dti";
- yang-version 1;
-
- revision 2016-06-06 {
- description
- "Initial revision.";
- }
-
- list augmented-list {
- key list-key;
-
- leaf list-key {
- type uint16;
- }
-
- leaf list-value {
- type string;
- }
- }
-}
+++ /dev/null
-module deserializer-test {
- namespace "deserializer:test";
- prefix "dt";
- yang-version 1;
-
- import deserializer-test-included { prefix dti; revision-date 2016-06-06; }
-
- revision 2016-06-06 {
- description
- "Initial revision.";
- }
-
- container contA {
- leaf-list leaf-list-A {
- type string;
- }
-
- leaf leaf-A {
- type string;
- }
-
- list list-A {
- key list-key;
-
- leaf list-key {
- type uint8;
- }
-
- leaf-list leaf-list-AA {
- type string;
- }
- }
- }
-
- leaf-list leaf-list-0 {
- type boolean;
- }
-
- leaf leaf-0 {
- type string;
- }
-
- list list-no-key {
- leaf name {
- type string;
- }
-
- leaf number {
- type uint8;
- }
- }
-
- list list-one-key {
- key name;
-
- leaf name {
- type string;
- }
-
- leaf number {
- type uint8;
- }
- }
-
- list list-multiple-keys {
- key "name number enabled";
-
- leaf name {
- type string;
- }
-
- leaf number {
- type uint8;
- }
-
- leaf enabled {
- type boolean;
- }
-
- leaf string-value {
- type string;
- }
- }
-
- augment "/dti:augmented-list" {
- leaf augmented-leaf {
- type string;
- }
- }
-}
+++ /dev/null
-module list-test {
- namespace "list:test";
- prefix "listt";
-
- revision 2016-04-29 {
- description
- "Initial revision.";
- }
-
- container top {
- list list1 {
- key "key1 key2 key3";
- leaf key1 {
- type string;
- }
- leaf key2 {
- type string;
- }
- leaf key3 {
- type string;
- }
- list list2 {
- key "key4 key5";
- leaf key4 {
- type string;
- }
- leaf key5 {
- type string;
- }
- leaf result {
- type string;
- }
- }
- }
- leaf-list Y {
- type uint32;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-module serializer-test-included {
- namespace "serializer:test:included";
- prefix "sti";
- yang-version 1;
-
- revision 2016-06-06 {
- description
- "Initial revision.";
- }
-
- list augmented-list {
- key list-key;
-
- leaf list-key {
- type uint16;
- }
-
- leaf list-value {
- type string;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-module serializer-test {
- namespace "serializer:test";
- prefix "st";
- yang-version 1;
-
- import serializer-test-included { prefix sti; revision-date 2016-06-06; }
-
- revision 2016-06-06 {
- description
- "Initial revision.";
- }
-
- container contA {
- leaf-list leaf-list-A {
- type string;
- }
-
- leaf leaf-A {
- type string;
- }
-
- list list-A {
- key list-key;
-
- leaf list-key {
- type uint8;
- }
-
- leaf-list leaf-list-AA {
- type string;
- }
- }
- }
-
- leaf-list leaf-list-0 {
- type boolean;
- }
-
- leaf leaf-0 {
- type string;
- }
-
- list list-no-key {
- leaf name {
- type string;
- }
-
- leaf number {
- type uint8;
- }
- }
-
- list list-one-key {
- key name;
-
- leaf name {
- type string;
- }
-
- leaf number {
- type uint8;
- }
- }
-
- list list-multiple-keys {
- key "name number enabled";
-
- leaf name {
- type string;
- }
-
- leaf number {
- type uint8;
- }
-
- leaf enabled {
- type boolean;
- }
- }
-
- augment "/sti:augmented-list" {
- leaf augmented-leaf {
- type string;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-module sal-remote {
-
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote";
- prefix "sal-remote";
-
- organization "Cisco Systems, Inc.";
- contact "Martin Bobak <mbobak@cisco.com>";
-
- description
- "This module contains the definition of methods related to
- sal remote model.
-
- Copyright (c)2013 Cisco Systems, Inc. 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";
-
- revision "2014-01-14" {
- description
- "Initial revision";
- }
-
-
- typedef q-name {
- type string;
- reference
- "http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#QName";
- }
-
- rpc create-data-change-event-subscription {
- input {
- leaf path {
- type instance-identifier;
- description "Subtree path. ";
- }
- }
- output {
- leaf stream-name {
- type string;
- description "Notification stream name.";
- }
- }
- }
-
- rpc create-data-change-event-subscription2 {
- input {
- leaf path2 {
- type instance-identifier;
- description "Subtree path. ";
- }
- }
- output {
- leaf stream-name2 {
- type string;
- description "Notification stream name.";
- }
- }
- }
-
- notification data-changed-notification {
- description "Data change notification.";
- list data-change-event {
- key path;
- leaf path {
- type instance-identifier;
- }
- leaf store {
- type enumeration {
- enum config;
- enum operation;
- }
- }
- leaf operation {
- type enumeration {
- enum created;
- enum updated;
- enum deleted;
- }
- }
- anyxml data{
- description "DataObject ";
- }
- }
- }
-
- rpc create-notification-stream {
- input {
- leaf-list notifications {
- type q-name;
- description "Notification QNames";
- }
- }
- output {
- leaf notification-stream-identifier {
- type string;
- description "Unique notification stream identifier, in which notifications will be propagated";
- }
- }
- }
-
- rpc begin-transaction{
- output{
- anyxml data-modification-transaction{
- description "DataModificationTransaction xml";
- }
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
- module toaster {
-
- yang-version 1;
-
- namespace
- "http://netconfcentral.org/ns/toaster";
-
- prefix toast;
-
- organization "Netconf Central";
-
- contact
- "Andy Bierman <andy@netconfcentral.org>";
-
- description
- "YANG version of the TOASTER-MIB.";
-
- revision "2009-11-20" {
- description
- "Toaster module in progress.";
- }
-
-
- identity toast-type {
- description
- "Base for all bread types supported by the toaster.
- New bread types not listed here nay be added in the
- future.";
- }
-
- identity white-bread {
- base toast:toast-type;
- description "White bread.";
- }
-
- identity wheat-bread {
- base toast-type;
- description "Wheat bread.";
- }
-
- identity wonder-bread {
- base toast-type;
- description "Wonder bread.";
- }
-
- identity frozen-waffle {
- base toast-type;
- description "Frozen waffle.";
- }
-
- identity frozen-bagel {
- base toast-type;
- description "Frozen bagel.";
- }
-
- identity hash-brown {
- base toast-type;
- description "Hash browned potatos.";
- }
-
- typedef DisplayString {
- type string {
- length "0 .. 255";
- }
- description
- "YANG version of the SMIv2 DisplayString TEXTUAL-CONVENTION.";
- reference
- "RFC 2579, section 2.";
-
- }
-
- container toaster {
- presence
- "Indicates the toaster service is available";
- description
- "Top-level container for all toaster database objects.";
- leaf toasterManufacturer {
- type DisplayString;
- config false;
- mandatory true;
- description
- "The name of the toaster's manufacturer. For instance,
- Microsoft Toaster.";
- }
-
- leaf toasterModelNumber {
- type DisplayString;
- config false;
- mandatory true;
- description
- "The name of the toaster's model. For instance,
- Radiant Automatic.";
- }
-
- leaf toasterStatus {
- type enumeration {
- enum "up" {
- value 1;
- description
- "The toaster knob position is up.
- No toast is being made now.";
- }
- enum "down" {
- value 2;
- description
- "The toaster knob position is down.
- Toast is being made now.";
- }
- }
- config false;
- mandatory true;
- description
- "This variable indicates the current state of
- the toaster.";
- }
- } // container toaster
-
- rpc make-toast {
- description
- "Make some toast.
- The toastDone notification will be sent when
- the toast is finished.
- An 'in-use' error will be returned if toast
- is already being made.
- A 'resource-denied' error will be returned
- if the toaster service is disabled.";
- input {
- leaf toasterDoneness {
- type uint32 {
- range "1 .. 10";
- }
- default '5';
- description
- "This variable controls how well-done is the
- ensuing toast. It should be on a scale of 1 to 10.
- Toast made at 10 generally is considered unfit
- for human consumption; toast made at 1 is warmed
- lightly.";
- }
-
- leaf toasterToastType {
- type identityref {
- base toast:toast-type;
- }
- default 'wheat-bread';
- description
- "This variable informs the toaster of the type of
- material that is being toasted. The toaster
- uses this information, combined with
- toasterDoneness, to compute for how
- long the material must be toasted to achieve
- the required doneness.";
- }
- }
- } // rpc make-toast
-
- rpc testOutput {
- output {
- leaf textOut {
- type string;
- }
- }
- }
-
- rpc cancel-toast {
- description
- "Stop making toast, if any is being made.
- A 'resource-denied' error will be returned
- if the toaster service is disabled.";
- } // rpc cancel-toast
-
- notification toastDone {
- description
- "Indicates that the toast in progress has completed.";
- leaf toastStatus {
- type enumeration {
- enum "done" {
- value 0;
- description "The toast is done.";
- }
- enum "cancelled" {
- value 1;
- description
- "The toast was cancelled.";
- }
- enum "error" {
- value 2;
- description
- "The toaster service was disabled or
- the toaster is broken.";
- }
- }
- description
- "Indicates the final toast status";
- }
- } // notification toastDone
- } // module toaster
+++ /dev/null
-module mount-interface {
- yang-version 1;
- namespace "urn:ietf:params:xml:ns:yang:mount-interface";
- prefix "sn";
-
- description
- "test file";
-
- revision "2014-07-01" {
- description
- "Initial revision";
- reference "will be defined";
- }
-
- container interfaces {
- list interface {
- key "name";
-
- leaf name {
- type string;
- }
- leaf type {
- type string;
- }
- leaf enabled {
- type string;
- }
- }
- }
-}
+++ /dev/null
-module mount-interface2 {
- yang-version 1;
- namespace "urn:ietf:params:xml:ns:yang:mount-interface2";
- prefix "snn";
-
- description
- "test file";
-
- revision "2014-08-01" {
- description
- "Initial revision";
- reference "will be defined";
- }
-
- container class {
- list student {
- key "name";
-
- leaf name {
- type string;
- }
- leaf age {
- type string;
- }
- }
- }
-}
+++ /dev/null
-<block xmlns="urn:ietf:params:xml:ns:yang:test-interface">
- <address>456</address>
- <location>First</location>
-</block>
\ No newline at end of file
+++ /dev/null
-<student xmlns="urn:ietf:params:xml:ns:yang:test-interface2">
- <name>Vojtech</name>
- <age>17</age>
-</student>
\ No newline at end of file
+++ /dev/null
-<interfaces xmlns="urn:ietf:params:xml:ns:yang:test-interface">
- <interface>
- <name>eth0</name>
- <type>ethernetCsmacd</type>
- <enabled>false</enabled>
- </interface>
-</interfaces>
-
+++ /dev/null
-<interface>
- <name>eth0</name>
- <type>ethernetCsmacd</type>
- <enabled>false</enabled>
-</interface>
+++ /dev/null
-<class xmlns="urn:ietf:params:xml:ns:yang:test-interface2">
- <student>
- <name>Thomas</name>
- <age>23</age>
- </student>
-</class>
+++ /dev/null
-module test-interface {
- yang-version 1;
- namespace "urn:ietf:params:xml:ns:yang:test-interface";
- prefix "sn";
-
- description
- "test file";
-
- revision "2014-07-01" {
- description
- "Initial revision";
- reference "will be defined";
- }
-
- container interfaces {
-
- container block {
-
- leaf address {
- type string;
- }
- leaf location {
- type string;
- }
- }
-
- list interface {
- key "name";
-
- list sub-interface {
- key "sub-name";
-
- leaf sub-name {
- type string;
- }
- }
-
- leaf name {
- type string;
- }
- leaf type {
- type string;
- }
- leaf enabled {
- type string;
- }
- }
- }
-}
+++ /dev/null
-module test-interface2 {
- yang-version 1;
- namespace "urn:ietf:params:xml:ns:yang:test-interface2";
- prefix "snn";
-
- description
- "test file";
-
- revision "2014-08-01" {
- description
- "Initial revision";
- reference "will be defined";
- }
-
- container class {
- list student {
- key "name";
-
- leaf name {
- type string;
- }
- leaf age {
- type string;
- }
- }
- }
-}
+++ /dev/null
-<cont xmlns="generalnamespace">
- <cont1>
- <lf1 xmlns:prefix="prefix:name" xmlns:prefix2="prefix2:name">/prefix:somepath1/prefix2:somepath2</lf1>
- </cont1>
-</cont>
\ No newline at end of file
+++ /dev/null
-module data-container-yang {
- namespace "data:container:yang";
-
- prefix "dtconyg";
- revision 2013-11-19 {
- }
-
- container cont {
- leaf lf1 {
- type string;
- }
-
- leaf lf2 {
- type string;
- }
-
- leaf lf3 {
- type empty;
- }
-
- leaf-list lflst1 {
- type string;
- }
- list lst1 {
- leaf lf11 {
- type string;
- }
- }
- container cont1 {
- leaf lf11 {
- type uint8;
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-<cont>
- <lf1>str0</lf1>
- <lf2></lf2>
- <lf3/>
- <lflst1>121</lflst1>
- <lflst1>131</lflst1>
- <lflst1>str1</lflst1>
- <lst1>
- <lf11>str2</lf11>
- </lst1>
- <cont1>
- <lf11>100</lf11>
- </cont1>
-</cont>
+++ /dev/null
-module data-container-yang {
- namespace "data:container:yang";
-
- prefix "dtconyg";
- revision 2013-11-19 {
- }
-
- container cont {
- list lst1 {
- leaf lf11 {
- type string;
- }
- leaf-list lflst11 {
- type string;
- }
- list lst11 {
- leaf lf111 {
- type string;
- }
- }
- container cont11 {
- leaf lf111 {
- type uint8;
- }
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-module data-list-yang {
- namespace "data:list:yang";
-
- prefix "dtlstyg";
-
- import data-container-yang {
- prefix "dtconyg";
- revision-date 2013-11-19;
- }
-
-
- revision 2013-11-19 {
- }
-
-
-
- augment "/dtconyg:cont" {
- leaf lf1 {
- type string;
- }
- }
-}
+++ /dev/null
-<cont>
- <lst1>
- <lf11>str0</lf11>
- <lflst11>121</lflst11>
- <lflst11>131</lflst11>
- <lflst11>str1</lflst11>
- <lst11>
- <lf111>str2</lf111>
- </lst11>
- <cont11>
- <lf111>100</lf111>
- </cont11>
- </lst1>
- <lst1>
- <lflst11>221</lflst11>
- <cont11>
- <lf111>100</lf111>
- </cont11>
- </lst1>
- <lf1>lf1</lf1>
-</cont>
+++ /dev/null
-<cont xmlns:x="x:namespace" xmlns:y="y:namespace">
- <cont1 xmlns:z="z:namespace" xmlns:a="a:namespace" xmlns:b="b:namespace">
- <lf11 xmlns:c="identity:module">c:iden</lf11>
- </cont1>
-</cont>
\ No newline at end of file
+++ /dev/null
-module module1 {
- namespace "module:one";
-
- prefix "m1";
- revision 2014-01-17 {
- }
-
- container cont_m1 {
- leaf lf1_m1 {
- type string;
- }
- }
- container contB_m1 {
- }
-
-}
\ No newline at end of file
+++ /dev/null
-module module2 {
- namespace "module:two";
-
- prefix "m2";
- revision 2014-01-17 {
- }
-
- container cont_m2 {
- leaf lf1_m2 {
- type string;
- }
- }
- container contB_m2 {
- }
-
-
-}
\ No newline at end of file
+++ /dev/null
-<cont>
- <lf1></lf1>
- <lflst1></lflst1>
- <lflst1></lflst1>
- <lst1>
- <lf11></lf11>
- </lst1>
-</cont>
+++ /dev/null
-module identity-module {
- namespace "identity:module";
-
- prefix "idemod";
- revision 2013-12-02 {
- }
-
- identity iden {
- }
-}
+++ /dev/null
-module identityref-module {
- namespace "identityref:module";
-
- prefix "iderefmod";
-
- import identity-module {prefix idemo; revision-date 2013-12-02;}
-
- revision 2013-12-02 {
- }
-
- container cont {
- container cont1 {
- leaf lf11 {
- type identityref {
- base "idemo:iden";
- }
- }
- }
- }
-
-}
+++ /dev/null
-<cont xmlns="general:module" xmlns:x="x:namespace" xmlns:y="y:namespace">
- <cont1 xmlns:z="z:namespace" xmlns:a="a:namespace" xmlns:b="b:namespace">
- <lf11 xmlns="identityref:module" xmlns:c="c:namespace">iden</lf11>
- </cont1>
-</cont>
\ No newline at end of file
+++ /dev/null
-<cont xmlns:x="x:namespace" xmlns:y="y:namespace">
- <cont1 xmlns="identityref:module" xmlns:z="z:namespace" xmlns:a="a:namespace" xmlns:b="b:namespace">
- <lf11 xmlns:c="c:namespace">iden</lf11>
- </cont1>
-</cont>
\ No newline at end of file
+++ /dev/null
-<cont xmlns="identityref:module" xmlns:x="x:namespace" xmlns:y="y:namespace">
- <cont1 xmlns:z="z:namespace" xmlns:a="a:namespace" xmlns:b="b:namespace">
- <lf11 xmlns:c="identity:module">c:iden</lf11>
- </cont1>
-</cont>
\ No newline at end of file
+++ /dev/null
-<cont xmlns="identityref:module" xmlns:x="x:namespace" xmlns:y="y:namespace">
- <cont1 xmlns:c="identity:module" xmlns:z="z:namespace" xmlns:a="a:namespace" xmlns:b="b:namespace">
- <lf11>z:iden</lf11>
- </cont1>
-</cont>
\ No newline at end of file
+++ /dev/null
-<cont>
- <cont1>
- <lf11>x:iden</lf11>
- </cont1>
-</cont>
\ No newline at end of file
+++ /dev/null
-<cont>
- <cont1>
- <lf11>iden</lf11>
- </cont1>
-</cont>
\ No newline at end of file
+++ /dev/null
-module general-module {
- namespace "general:module";
-
- prefix "genmod";
- revision 2013-12-12 {
- }
-
- container cont {
- container cont1 {
- }
- }
-
-
-}
\ No newline at end of file
+++ /dev/null
-module identity-module {
- namespace "identity:module";
-
- prefix "idemod";
- revision 2013-12-02 {
- }
-
- identity iden {
- }
-}
+++ /dev/null
-module identityref-module {
- namespace "identityref:module";
-
- prefix "iderefmod";
-
- import identity-module {prefix idemo; revision-date 2013-12-02;}
- import general-module {prefix gmo; revision-date 2013-12-12;}
-
- revision 2013-12-02 {
- }
-
- augment "/gmo:cont/gmo:cont1" {
- leaf lf11 {
- type identityref {
- base "idemo:iden";
- }
- }
- }
-
-}
+++ /dev/null
-module leafref-module {
- namespace "leafref:module";
-
- prefix "lfrfmo";
- revision 2013-11-18 {
- }
-
- identity base {}
-
- container cont {
- leaf lf1 {
- type int32;
- }
- leaf lf2 {
- type leafref {
- path "/cont/lf1";
- }
- }
-
- leaf lf-ident {
- type identityref {
- base "lfrfmo:base";
- }
- }
-
- leaf lf-ident-ref {
- type leafref {
- path "/cont/lf-ident";
- }
- }
-
- leaf lf-ident-ref-relative {
- type leafref {
- path "../lf-ident";
- }
- }
-
- leaf lf-ident-ref-relative-cnd {
- type leafref {
- path "/lfrfmo:cont/lfrfmo:lis[lfrfmo:id='abc']/lf-ident-ref";
- }
- }
-
-
- list lis {
- key "id";
-
- leaf id {
- type string;
- }
-
- leaf lf-ident-ref {
- type leafref {
- path "/cont/lf-ident";
- }
- }
- }
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-<cont>
- <lf1>121</lf1>
- <lf2>121</lf2>
- <lf-ident xmlns:a="leafref:module">a:base</lf-ident>
- <lf-ident-ref xmlns:a="leafref:module">a:base</lf-ident-ref>
- <lf-ident-ref-relative xmlns:a="leafref:module">a:base</lf-ident-ref-relative>
- <lf-ident-ref-relative-cnd xmlns:a="leafref:module">a:base</lf-ident-ref-relative-cnd>
-</cont>
\ No newline at end of file