Split Restconf implementations (draft02 and RFC) - Application 19/62919/9
authorJakub Toth <jakub.toth@pantheon.tech>
Fri, 8 Sep 2017 12:02:11 +0000 (14:02 +0200)
committerJakub Toth <jakub.toth@pantheon.tech>
Wed, 13 Sep 2017 10:52:17 +0000 (10:52 +0000)
  * add blueprint + web.xml for restconf-nb-rfc8040

Change-Id: Ifd8ea387ace5580ddd36dde59000b7cd69515272
Signed-off-by: Jakub Toth <jakub.toth@pantheon.tech>
35 files changed:
restconf/restconf-nb-rfc8040/pom.xml
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/RestconfApplication.java [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/api/JSONRestconfService.java [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/JSONRestconfServiceRfc8040Impl.java [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/main/resources/WEB-INF/web.xml [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/main/resources/org/opendaylight/blueprint/restconf-bp.xml [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/JSONRestconfServiceRfc8040ImplTest.java [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/full-versions/make-toast-rpc-input.json [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data-rpc-input.json [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data-rpc-input.xml [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data2.xml [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data3.xml [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data4.xml [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data5.xml [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data6.xml [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data7.xml [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-module/test-module.yang [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/full-versions/testCont1Data.json [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/full-versions/testData.json [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/full-versions/testData.xml [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/ex-vlan.yang [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/iana-if-type.yang [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/ietf-interfaces@2013-07-04.yang [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/ietf-yang-types@2013-05-16.yang [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/sal-remote@2014-01-14.yang [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/simple-nodes.yang [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/subscribe-to-notification.yang [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/toaster.yang [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/parts/ietf-interfaces_interfaces.json [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/parts/ietf-interfaces_interfaces.xml [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/parts/ietf-interfaces_interfaces2.xml [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/parts/ietf-interfaces_interfaces_absolute_path.json [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/parts/ietf-interfaces_interfaces_absolute_path.xml [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/parts/ietf-interfaces_interfaces_absolute_path2.xml [new file with mode: 0644]
restconf/restconf-nb-rfc8040/src/test/resources/parts/ietf-interfaces_interfaces_interface_absolute_path.xml [new file with mode: 0644]

index e202a0b5676dc469b3bd07f91b11292fd797fdb3..8997a6741005c7a761065941509db33ee50eca77 100644 (file)
       <artifactId>stax-utils</artifactId>
     </dependency>
 
+    <dependency>
+      <groupId>org.opendaylight.aaa</groupId>
+      <artifactId>aaa-shiro-api</artifactId>
+    </dependency>
+
     <!-- Testing Dependencies -->
     <dependency>
       <groupId>org.glassfish.jersey.test-framework.providers</groupId>
           </classpathDependencyExcludes>
         </configuration>
       </plugin>
+<plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Bundle-Name>MD SAL Restconf Connector</Bundle-Name>
+            <Import-Package>
+              *,
+              com.sun.jersey.spi.container.servlet,
+              org.eclipse.jetty.servlets,
+              org.opendaylight.aaa.shiro.filters,
+              org.opendaylight.aaa.shiro.realm,
+              org.opendaylight.aaa.shiro.web.env,
+              org.opendaylight.aaa.filterchain.filters,
+              org.opendaylight.aaa.api,
+              org.apache.shiro.web.env
+            </Import-Package>
+            <Web-ContextPath>/restconf/rfc</Web-ContextPath>
+          </instructions>
+        </configuration>
+      </plugin>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-checkstyle-plugin</artifactId>
diff --git a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/RestconfApplication.java b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/RestconfApplication.java
new file mode 100644 (file)
index 0000000..e779281
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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.nb.rfc8040;
+
+import com.google.common.collect.ImmutableSet;
+import java.util.HashSet;
+import java.util.Set;
+import javax.ws.rs.core.Application;
+import org.opendaylight.restconf.nb.rfc8040.jersey.providers.JsonNormalizedNodeBodyReader;
+import org.opendaylight.restconf.nb.rfc8040.jersey.providers.NormalizedNodeJsonBodyWriter;
+import org.opendaylight.restconf.nb.rfc8040.jersey.providers.NormalizedNodeXmlBodyWriter;
+import org.opendaylight.restconf.nb.rfc8040.jersey.providers.XmlNormalizedNodeBodyReader;
+import org.opendaylight.restconf.nb.rfc8040.jersey.providers.patch.JsonToPatchBodyReader;
+import org.opendaylight.restconf.nb.rfc8040.jersey.providers.patch.PatchJsonBodyWriter;
+import org.opendaylight.restconf.nb.rfc8040.jersey.providers.patch.PatchXmlBodyWriter;
+import org.opendaylight.restconf.nb.rfc8040.jersey.providers.patch.XmlToPatchBodyReader;
+import org.opendaylight.restconf.nb.rfc8040.jersey.providers.schema.SchemaExportContentYangBodyWriter;
+import org.opendaylight.restconf.nb.rfc8040.jersey.providers.schema.SchemaExportContentYinBodyWriter;
+import org.opendaylight.restconf.nb.rfc8040.services.wrapper.ServicesWrapperImpl;
+
+public class RestconfApplication extends Application {
+
+    @Override
+    public Set<Class<?>> getClasses() {
+        return ImmutableSet.<Class<?>>builder()
+                .add(NormalizedNodeJsonBodyWriter.class).add(NormalizedNodeXmlBodyWriter.class)
+                .add(JsonNormalizedNodeBodyReader.class).add(XmlNormalizedNodeBodyReader.class)
+                .add(SchemaExportContentYinBodyWriter.class).add(SchemaExportContentYangBodyWriter.class)
+                .add(JsonToPatchBodyReader.class).add(XmlToPatchBodyReader.class)
+                .add(PatchJsonBodyWriter.class).add(PatchXmlBodyWriter.class)
+                .build();
+    }
+
+    @Override
+    public Set<Object> getSingletons() {
+        final Set<Object> singletons = new HashSet<>();
+        singletons.add(ServicesWrapperImpl.getInstance());
+        return singletons;
+    }
+}
diff --git a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/api/JSONRestconfService.java b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/api/JSONRestconfService.java
new file mode 100644 (file)
index 0000000..39fceed
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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.restconf.nb.rfc8040.rests.services.api;
+
+import com.google.common.base.Optional;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.common.api.data.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;
+}
diff --git a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/JSONRestconfServiceRfc8040Impl.java b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/JSONRestconfServiceRfc8040Impl.java
new file mode 100644 (file)
index 0000000..5ba852a
--- /dev/null
@@ -0,0 +1,366 @@
+/*
+ * 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.restconf.nb.rfc8040.rests.services.impl;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.List;
+import javax.annotation.Nullable;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.PathSegment;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
+import org.opendaylight.restconf.common.context.NormalizedNodeContext;
+import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
+import org.opendaylight.restconf.common.errors.RestconfError;
+import org.opendaylight.restconf.common.errors.RestconfError.ErrorTag;
+import org.opendaylight.restconf.nb.rfc8040.handlers.DOMMountPointServiceHandler;
+import org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler;
+import org.opendaylight.restconf.nb.rfc8040.jersey.providers.JsonNormalizedNodeBodyReader;
+import org.opendaylight.restconf.nb.rfc8040.jersey.providers.NormalizedNodeJsonBodyWriter;
+import org.opendaylight.restconf.nb.rfc8040.rests.services.api.JSONRestconfService;
+import org.opendaylight.restconf.nb.rfc8040.rests.services.api.TransactionServicesWrapper;
+import org.opendaylight.restconf.nb.rfc8040.rests.utils.RestconfDataServiceConstant;
+import org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserIdentifier;
+import org.opendaylight.yangtools.yang.common.OperationFailedException;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation of the JSONRestconfService interface using the restconf Draft18 implementation.
+ *
+ * @author Thomas Pantelis
+ */
+public class JSONRestconfServiceRfc8040Impl implements JSONRestconfService, AutoCloseable {
+    private static final Logger LOG = LoggerFactory.getLogger(JSONRestconfServiceRfc8040Impl.class);
+
+    private static final Annotation[] EMPTY_ANNOTATIONS = new Annotation[0];
+
+    private final TransactionServicesWrapper services;
+    private final DOMMountPointServiceHandler mountPointServiceHandler;
+
+    public JSONRestconfServiceRfc8040Impl(final TransactionServicesWrapper services,
+            final DOMMountPointServiceHandler mountPointServiceHandler) {
+        this.services = services;
+        this.mountPointServiceHandler = mountPointServiceHandler;
+    }
+
+    @SuppressWarnings("checkstyle:IllegalCatch")
+    @Override
+    public void put(final String uriPath, final String payload) throws OperationFailedException {
+        Preconditions.checkNotNull(payload, "payload can't be null");
+
+        LOG.debug("put: uriPath: {}, payload: {}", uriPath, payload);
+
+        final NormalizedNodeContext context = toNormalizedNodeContext(uriPath, payload, false);
+
+        LOG.debug("Parsed YangInstanceIdentifier: {}", context.getInstanceIdentifierContext().getInstanceIdentifier());
+        LOG.debug("Parsed NormalizedNode: {}", context.getData());
+
+        try {
+            services.putData(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 {
+        Preconditions.checkNotNull(payload, "payload can't be null");
+
+        LOG.debug("post: uriPath: {}, payload: {}", uriPath, payload);
+
+        final NormalizedNodeContext context = toNormalizedNodeContext(uriPath, payload, true);
+
+        LOG.debug("Parsed YangInstanceIdentifier: {}", context.getInstanceIdentifierContext().getInstanceIdentifier());
+        LOG.debug("Parsed NormalizedNode: {}", context.getData());
+
+        try {
+            services.postData(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 {
+            services.deleteData(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 {
+            final MultivaluedMap<String, String> queryParams = new MultivaluedHashMap<>();
+            queryParams.putSingle(RestconfDataServiceConstant.ReadData.CONTENT,
+                    datastoreType == LogicalDatastoreType.CONFIGURATION ? RestconfDataServiceConstant.ReadData.CONFIG :
+                        RestconfDataServiceConstant.ReadData.NONCONFIG);
+
+            final Response response = services.readData(uriPath, new SimpleUriInfo(uriPath, queryParams));
+            final NormalizedNodeContext readData = (NormalizedNodeContext) response.getEntity();
+
+            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.absent();
+        }
+    }
+
+    @SuppressWarnings("checkstyle:IllegalCatch")
+    @Override
+    public Optional<String> invokeRpc(final String uriPath, final Optional<String> input)
+            throws OperationFailedException {
+        Preconditions.checkNotNull(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 {
+            final NormalizedNodeContext inputContext = toNormalizedNodeContext(uriPath, actualInput, true);
+
+            LOG.debug("Parsed YangInstanceIdentifier: {}", inputContext.getInstanceIdentifierContext()
+                    .getInstanceIdentifier());
+            LOG.debug("Parsed NormalizedNode: {}", inputContext.getData());
+
+            final NormalizedNodeContext outputContext =
+                    services.invokeRpc(uriPath, inputContext, new SimpleUriInfo(uriPath));
+
+            if (outputContext.getData() != null) {
+                output = toJson(outputContext);
+            }
+        } catch (final Exception e) {
+            propagateExceptionAs(uriPath, e, "RPC");
+        }
+
+        return Optional.fromNullable(output);
+    }
+
+    @Override
+    public void close() {
+    }
+
+    private NormalizedNodeContext toNormalizedNodeContext(final String uriPath, @Nullable final String payload,
+            final boolean isPost) throws OperationFailedException {
+        final InstanceIdentifierContext<?> instanceIdentifierContext = ParserIdentifier.toInstanceIdentifier(
+                uriPath, SchemaContextHandler.getActualSchemaContext(),
+                Optional.of(mountPointServiceHandler.get()));
+
+        if (payload == null) {
+            return new NormalizedNodeContext(instanceIdentifierContext, null);
+        }
+
+        final InputStream entityStream = new ByteArrayInputStream(payload.getBytes(StandardCharsets.UTF_8));
+        try {
+            return JsonNormalizedNodeBodyReader.readFrom(instanceIdentifierContext, entityStream, isPost);
+        } catch (final IOException e) {
+            propagateExceptionAs(uriPath, e, "GET");
+            return null;
+        }
+    }
+
+    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.name());
+    }
+
+    private static boolean isDataMissing(final Exception exception) {
+        if (exception instanceof RestconfDocumentedException) {
+            final RestconfDocumentedException rde = (RestconfDocumentedException)exception;
+            return !rde.getErrors().isEmpty() && rde.getErrors().get(0).getErrorTag() == ErrorTag.DATA_MISSING;
+        }
+
+        return false;
+    }
+
+    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(toRpcErrorType(e.getErrorType()), e.getErrorTag().getTagValue(),
+                    e.getErrorMessage());
+        }
+
+        return to;
+    }
+
+    private static ErrorType toRpcErrorType(final RestconfError.ErrorType errorType) {
+        switch (errorType) {
+            case TRANSPORT:
+                return ErrorType.TRANSPORT;
+            case RPC:
+                return ErrorType.RPC;
+            case PROTOCOL:
+                return ErrorType.PROTOCOL;
+            default:
+                return ErrorType.APPLICATION;
+        }
+    }
+
+    private static class SimpleUriInfo implements UriInfo {
+        private final String path;
+        private final MultivaluedMap<String, String> queryParams;
+
+        SimpleUriInfo(final String path) {
+            this(path, new MultivaluedHashMap<>());
+        }
+
+        SimpleUriInfo(final String path, final MultivaluedMap<String, String> queryParams) {
+            this.path = path;
+            this.queryParams = queryParams;
+        }
+
+        @Override
+        public String getPath() {
+            return path;
+        }
+
+        @Override
+        public String getPath(final boolean decode) {
+            return path;
+        }
+
+        @Override
+        public List<PathSegment> getPathSegments() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public List<PathSegment> getPathSegments(final boolean decode) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public URI getRequestUri() {
+            return URI.create(path);
+        }
+
+        @Override
+        public UriBuilder getRequestUriBuilder() {
+            return UriBuilder.fromUri(getRequestUri());
+        }
+
+        @Override
+        public URI getAbsolutePath() {
+            return getRequestUri();
+        }
+
+        @Override
+        public UriBuilder getAbsolutePathBuilder() {
+            return UriBuilder.fromUri(getAbsolutePath());
+        }
+
+        @Override
+        public URI getBaseUri() {
+            return URI.create("");
+        }
+
+        @Override
+        public UriBuilder getBaseUriBuilder() {
+            return UriBuilder.fromUri(getBaseUri());
+        }
+
+        @Override
+        public MultivaluedMap<String, String> getPathParameters() {
+            return new MultivaluedHashMap<>();
+        }
+
+        @Override
+        public MultivaluedMap<String, String> getPathParameters(final boolean decode) {
+            return getPathParameters();
+        }
+
+        @Override
+        public MultivaluedMap<String, String> getQueryParameters() {
+            return queryParams;
+        }
+
+        @Override
+        public MultivaluedMap<String, String> getQueryParameters(final boolean decode) {
+            return getQueryParameters();
+        }
+
+        @Override
+        public List<String> getMatchedURIs() {
+            return Collections.emptyList();
+        }
+
+        @Override
+        public List<String> getMatchedURIs(final boolean decode) {
+            return getMatchedURIs();
+        }
+
+        @Override
+        public List<Object> getMatchedResources() {
+            return Collections.emptyList();
+        }
+
+        @Override
+        public URI resolve(final URI uri) {
+            return uri;
+        }
+
+        @Override
+        public URI relativize(final URI uri) {
+            return uri;
+        }
+    }
+}
diff --git a/restconf/restconf-nb-rfc8040/src/main/resources/WEB-INF/web.xml b/restconf/restconf-nb-rfc8040/src/main/resources/WEB-INF/web.xml
new file mode 100644 (file)
index 0000000..a17ef96
--- /dev/null
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+    version="3.0">
+
+    <servlet>
+        <servlet-name>Restconf</servlet-name>
+        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
+        <init-param>
+            <param-name>javax.ws.rs.Application</param-name>
+            <param-value>org.opendaylight.restconf.nb.rfc8040.RestconfApplication</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+
+    <context-param>
+      <param-name>shiroEnvironmentClass</param-name>
+      <param-value>org.opendaylight.aaa.shiro.web.env.KarafIniWebEnvironment</param-value>
+    </context-param>
+
+    <listener>
+        <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
+    </listener>
+
+    <filter>
+        <filter-name>ShiroFilter</filter-name>
+        <filter-class>org.opendaylight.aaa.shiro.filters.AAAFilter</filter-class>
+    </filter>
+
+    <filter-mapping>
+        <filter-name>ShiroFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+
+    <filter>
+        <filter-name>DynamicFilterChain</filter-name>
+        <filter-class>org.opendaylight.aaa.filterchain.filters.CustomFilterAdapter</filter-class>
+    </filter>
+
+    <filter-mapping>
+        <filter-name>DynamicFilterChain</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+
+    <servlet-mapping>
+        <servlet-name>Restconf NB - RFC 8040</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+
+    <filter>
+        <filter-name>GzipFilter</filter-name>
+        <filter-class>org.eclipse.jetty.servlets.GzipFilter</filter-class>
+        <init-param>
+            <param-name>mimeTypes</param-name>
+            <param-value>application/xml,application/yang.data+xml,xml,application/json,application/yang.data+json</param-value>
+        </init-param>
+    </filter>
+    <filter-mapping>
+        <filter-name>GzipFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+
+    <filter>
+        <filter-name>cross-origin-restconf</filter-name>
+        <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
+        <init-param>
+            <param-name>allowedOrigins</param-name>
+            <param-value>*</param-value>
+        </init-param>
+        <init-param>
+            <param-name>allowedMethods</param-name>
+            <param-value>GET,POST,OPTIONS,DELETE,PUT,HEAD</param-value>
+        </init-param>
+        <init-param>
+            <param-name>allowedHeaders</param-name>
+            <param-value>origin, content-type, accept, authorization</param-value>
+        </init-param>
+        <init-param>
+            <param-name>exposedHeaders</param-name>
+            <param-value>location</param-value>
+        </init-param>
+    </filter>
+    <filter-mapping>
+        <filter-name>cross-origin-restconf</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+
+    <security-constraint>
+        <web-resource-collection>
+            <web-resource-name>NB RFC api</web-resource-name>
+            <url-pattern>/*</url-pattern>
+            <http-method>POST</http-method>
+            <http-method>GET</http-method>
+            <http-method>PUT</http-method>
+            <http-method>PATCH</http-method>
+            <http-method>DELETE</http-method>
+            <http-method>HEAD</http-method>
+        </web-resource-collection>
+    </security-constraint>
+
+</web-app>
diff --git a/restconf/restconf-nb-rfc8040/src/main/resources/org/opendaylight/blueprint/restconf-bp.xml b/restconf/restconf-nb-rfc8040/src/main/resources/org/opendaylight/blueprint/restconf-bp.xml
new file mode 100644 (file)
index 0000000..7eda5a3
--- /dev/null
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+           xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
+           xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
+           xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.4.0"
+           odl:use-default-for-reference-types="true">
+
+  <!-- Restconf providers -->
+  <!--
+    This cfg file defines the type of the DOMDataBroker service to use. 'default' indicates to use
+    the default DOMDataBroker provided by MD-SAL. This setting is useful for providing a custom
+    DOMDataBroker implementation that does, e.g., validation or additional security checking on
+    top of the default DOMDataBroker.
+  -->
+  <cm:property-placeholder persistent-id="org.opendaylight.restconf.databroker"
+        placeholder-prefix = "@{" placeholder-suffix = "}" update-strategy="reload">
+    <cm:default-properties>
+      <cm:property name="databroker-service-type" value="default"/>
+    </cm:default-properties>
+  </cm:property-placeholder>
+
+  <!-- We need the AAAService available even though we don't use it -->
+  <reference interface="org.opendaylight.aaa.api.AAAService"/>
+
+  <reference id="schemaService" interface="org.opendaylight.controller.sal.core.api.model.SchemaService"/>
+  <reference id="domRpcService" interface="org.opendaylight.controller.md.sal.dom.api.DOMRpcService"/>
+  <reference id="domMountPointService" interface="org.opendaylight.controller.md.sal.dom.api.DOMMountPointService"/>
+  <reference id="domNotificationService" interface="org.opendaylight.controller.md.sal.dom.api.DOMNotificationService"/>
+  <reference id="domDataBroker" interface="org.opendaylight.controller.md.sal.dom.api.DOMDataBroker"
+          ext:filter="(type=@{databroker-service-type})"/>
+
+  <bean id="restconfProvider" class="org.opendaylight.restconf.nb.rfc8040.RestConnectorProvider"
+          init-method="start" destroy-method="close">
+    <argument ref="domDataBroker"/>
+    <argument ref="schemaService"/>
+    <argument ref="domRpcService"/>
+    <argument ref="domNotificationService"/>
+    <argument ref="domMountPointService"/>
+  </bean>
+
+  <service ref="restconfProvider"
+      interface="org.opendaylight.restconf.nb.rfc8040.RestconfConnector" />
+
+  <!-- JSONRestconfService -->
+  <bean id="jsonRestconfService" depends-on="restconfProvider"
+      class="org.opendaylight.restconf.nb.rfc8040.rests.services.impl.JSONRestconfServiceRfc8040Impl"
+      destroy-method="close">
+    <argument>
+      <bean class="org.opendaylight.restconf.nb.rfc8040.services.wrapper.ServicesWrapperImpl"
+          factory-method="getInstance" />
+    </argument>
+    <argument>
+      <bean factory-ref="restconfProvider" factory-method="getMountPointServiceHandler" />
+    </argument>
+  </bean>
+
+  <service ref="jsonRestconfService" odl:type="rfc8040"
+      interface="org.opendaylight.restconf.nb.rfc8040.rests.services.api.JSONRestconfService" />
+
+</blueprint>
diff --git a/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/JSONRestconfServiceRfc8040ImplTest.java b/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/JSONRestconfServiceRfc8040ImplTest.java
new file mode 100644 (file)
index 0000000..4909e0f
--- /dev/null
@@ -0,0 +1,538 @@
+/*
+ * 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.restconf.nb.rfc8040.rests.services.impl;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isNull;
+import static org.mockito.Matchers.notNull;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import com.google.common.base.Optional;
+import com.google.common.io.Resources;
+import com.google.common.util.concurrent.Futures;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.Map;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationNotAvailableException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
+import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
+import org.opendaylight.restconf.nb.rfc8040.TestUtils;
+import org.opendaylight.restconf.nb.rfc8040.handlers.DOMDataBrokerHandler;
+import org.opendaylight.restconf.nb.rfc8040.handlers.DOMMountPointServiceHandler;
+import org.opendaylight.restconf.nb.rfc8040.handlers.NotificationServiceHandler;
+import org.opendaylight.restconf.nb.rfc8040.handlers.RpcServiceHandler;
+import org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler;
+import org.opendaylight.restconf.nb.rfc8040.handlers.TransactionChainHandler;
+import org.opendaylight.restconf.nb.rfc8040.services.wrapper.ServicesWrapperImpl;
+import org.opendaylight.yangtools.yang.common.OperationFailedException;
+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.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.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+
+/**
+ * Unit tests for JSONRestconfServiceDraft18.
+ *
+ * @author Thomas Pantelis
+ */
+public class JSONRestconfServiceRfc8040ImplTest {
+    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 SchemaContext schemaContext;
+
+    @Mock
+    private DOMTransactionChain mockTxChain;
+
+    @Mock
+    private DOMDataReadWriteTransaction mockReadWriteTx;
+
+    @Mock
+    private DOMDataReadOnlyTransaction mockReadOnlyTx;
+
+    @Mock
+    private DOMDataWriteTransaction mockWriteTx;
+
+    @Mock
+    private DOMMountPointService mockMountPointService;
+
+    @Mock
+    private SchemaContextHandler mockSchemaContextHandler;
+
+    @Mock
+    private DOMDataBroker mockDOMDataBroker;
+
+    @Mock
+    private DOMRpcService mockRpcService;
+
+    private JSONRestconfServiceRfc8040Impl service;
+
+    @BeforeClass
+    public static void init() throws IOException, ReactorException {
+        schemaContext = TestUtils.loadSchemaContext("/full-versions/yangs");
+        SchemaContextHandler.setActualSchemaContext(schemaContext);
+    }
+
+    @Before
+    public void setup() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(mockReadOnlyTx).read(
+                eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
+
+        doNothing().when(mockWriteTx).put(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class),
+                any(NormalizedNode.class));
+        doNothing().when(mockWriteTx).merge(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class),
+                any(NormalizedNode.class));
+        doNothing().when(mockWriteTx).delete(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
+        doReturn(Futures.immediateCheckedFuture(null)).when(mockWriteTx).submit();
+
+        doNothing().when(mockReadWriteTx).put(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class),
+                any(NormalizedNode.class));
+        doReturn(Futures.immediateCheckedFuture(null)).when(mockReadWriteTx).submit();
+        doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(mockReadWriteTx).read(
+                eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
+        doReturn(Futures.immediateCheckedFuture(Boolean.FALSE)).when(mockReadWriteTx).exists(
+                eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
+
+        doReturn(mockReadOnlyTx).when(mockTxChain).newReadOnlyTransaction();
+        doReturn(mockReadWriteTx).when(mockTxChain).newReadWriteTransaction();
+        doReturn(mockWriteTx).when(mockTxChain).newWriteOnlyTransaction();
+
+        doReturn(mockTxChain).when(mockDOMDataBroker).createTransactionChain(any());
+
+        doReturn(schemaContext).when(mockSchemaContextHandler).get();
+
+        final TransactionChainHandler txChainHandler = new TransactionChainHandler(mockTxChain);
+
+        final DOMMountPointServiceHandler mountPointServiceHandler =
+                new DOMMountPointServiceHandler(mockMountPointService);
+
+        ServicesWrapperImpl.getInstance().setHandlers(mockSchemaContextHandler, mountPointServiceHandler,
+                txChainHandler, new DOMDataBrokerHandler(mockDOMDataBroker),
+                new RpcServiceHandler(mockRpcService),
+                new NotificationServiceHandler(mock(DOMNotificationService.class)));
+
+        service = new JSONRestconfServiceRfc8040Impl(ServicesWrapperImpl.getInstance(), mountPointServiceHandler);
+    }
+
+    private static String loadData(final String path) throws IOException {
+        return Resources.asCharSource(JSONRestconfServiceRfc8040ImplTest.class.getResource(path),
+                StandardCharsets.UTF_8).read();
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Test
+    public void testPut() throws Exception {
+        final String uriPath = "ietf-interfaces:interfaces/interface=eth0";
+        final String payload = loadData("/parts/ietf-interfaces_interfaces.json");
+
+        this.service.put(uriPath, payload);
+
+        final ArgumentCaptor<YangInstanceIdentifier> capturedPath =
+                ArgumentCaptor.forClass(YangInstanceIdentifier.class);
+        final ArgumentCaptor<NormalizedNode> capturedNode = ArgumentCaptor.forClass(NormalizedNode.class);
+
+        verify(mockReadWriteTx).put(eq(LogicalDatastoreType.CONFIGURATION), capturedPath.capture(),
+                capturedNode.capture());
+
+        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.getNodeType());
+        verifyLeafNode(actualNode, NAME_QNAME, "eth0");
+        verifyLeafNode(actualNode, TYPE_QNAME, "ethernetCsmacd");
+        verifyLeafNode(actualNode, ENABLED_QNAME, Boolean.FALSE);
+        verifyLeafNode(actualNode, DESC_QNAME, "some interface");
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Test
+    public void testPutBehindMountPoint() throws Exception {
+        setupTestMountPoint();
+
+        final String uriPath = "ietf-interfaces:interfaces/yang-ext:mount/test-module:cont/cont1";
+        final String payload = loadData("/full-versions/testCont1Data.json");
+
+        this.service.put(uriPath, payload);
+
+        final ArgumentCaptor<YangInstanceIdentifier> capturedPath =
+                ArgumentCaptor.forClass(YangInstanceIdentifier.class);
+        final ArgumentCaptor<NormalizedNode> capturedNode = ArgumentCaptor.forClass(NormalizedNode.class);
+
+        verify(mockReadWriteTx).put(eq(LogicalDatastoreType.CONFIGURATION), capturedPath.capture(),
+                capturedNode.capture());
+
+        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.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 {
+        doReturn(Futures.immediateFailedCheckedFuture(new TransactionCommitFailedException("mock")))
+                .when(mockReadWriteTx).submit();
+
+        final String uriPath = "ietf-interfaces:interfaces/interface=eth0";
+        final String payload = loadData("/parts/ietf-interfaces_interfaces.json");
+
+        this.service.put(uriPath, payload);
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Test
+    public void testPost() throws Exception {
+        final String uriPath = null;
+        final String payload = loadData("/parts/ietf-interfaces_interfaces_absolute_path.json");
+
+        this.service.post(uriPath, payload);
+
+        final ArgumentCaptor<YangInstanceIdentifier> capturedPath =
+                ArgumentCaptor.forClass(YangInstanceIdentifier.class);
+        final ArgumentCaptor<NormalizedNode> capturedNode = ArgumentCaptor.forClass(NormalizedNode.class);
+
+        verify(mockReadWriteTx).put(eq(LogicalDatastoreType.CONFIGURATION), capturedPath.capture(),
+                capturedNode.capture());
+
+        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.getNodeType());
+
+        final Optional<DataContainerChild<?, ?>> mapChild = actualNode.getChild(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 = new NodeIdentifierWithPredicates(
+                INTERFACE_QNAME, NAME_QNAME, "eth0");
+        final Optional<MapEntryNode> entryChild = mapNode.getChild(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");
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Test
+    public void testPostBehindMountPoint() throws Exception {
+        setupTestMountPoint();
+
+        final String uriPath = "ietf-interfaces:interfaces/yang-ext:mount/test-module:cont";
+        final String payload = loadData("/full-versions/testCont1Data.json");
+
+        this.service.post(uriPath, payload);
+
+        final ArgumentCaptor<YangInstanceIdentifier> capturedPath =
+                ArgumentCaptor.forClass(YangInstanceIdentifier.class);
+        final ArgumentCaptor<NormalizedNode> capturedNode = ArgumentCaptor.forClass(NormalizedNode.class);
+
+        verify(mockReadWriteTx).put(eq(LogicalDatastoreType.CONFIGURATION), capturedPath.capture(),
+                capturedNode.capture());
+
+        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.getNodeType());
+        verifyLeafNode(actualNode, TEST_LF11_QNAME, "lf11 data");
+        verifyLeafNode(actualNode, TEST_LF12_QNAME, "lf12 data");
+    }
+
+    @Test(expected = TransactionCommitFailedException.class)
+    @SuppressWarnings("checkstyle:IllegalThrows")
+    public void testPostFailure() throws Throwable {
+        doReturn(Futures.immediateFailedCheckedFuture(new TransactionCommitFailedException("mock")))
+                .when(mockReadWriteTx).submit();
+
+        final String uriPath = null;
+        final String payload = loadData("/parts/ietf-interfaces_interfaces_absolute_path.json");
+
+        try {
+            this.service.post(uriPath, payload);
+        } catch (final OperationFailedException e) {
+            assertNotNull(e.getCause());
+            throw e.getCause();
+        }
+    }
+
+    @Test
+    public void testDelete() throws Exception {
+        doReturn(Futures.immediateCheckedFuture(Boolean.TRUE)).when(mockReadWriteTx).exists(
+                eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
+
+        final String uriPath = "ietf-interfaces:interfaces/interface=eth0";
+
+        this.service.delete(uriPath);
+
+        final ArgumentCaptor<YangInstanceIdentifier> capturedPath =
+                ArgumentCaptor.forClass(YangInstanceIdentifier.class);
+
+        verify(mockReadWriteTx).delete(eq(LogicalDatastoreType.CONFIGURATION), 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";
+
+        this.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 {
+        final String uriPath = "ietf-interfaces:interfaces";
+        this.service.get(uriPath, LogicalDatastoreType.CONFIGURATION);
+    }
+
+    @Test(expected = OperationFailedException.class)
+    public void testGetFailure() throws Exception {
+        final String invalidUriPath = "/ietf-interfaces:interfaces/invalid";
+        this.service.get(invalidUriPath, LogicalDatastoreType.CONFIGURATION);
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Test
+    public void testInvokeRpcWithInput() throws Exception {
+        final SchemaPath path = SchemaPath.create(true, MAKE_TOAST_QNAME);
+
+        final DOMRpcResult expResult = new DefaultDOMRpcResult((NormalizedNode<?, ?>)null);
+        doReturn(Futures.immediateCheckedFuture(expResult)).when(mockRpcService).invokeRpc(eq(path),
+                any(NormalizedNode.class));
+
+        final String uriPath = "toaster:make-toast";
+        final String input = loadData("/full-versions/make-toast-rpc-input.json");
+
+        final Optional<String> output = this.service.invokeRpc(uriPath, Optional.of(input));
+
+        assertEquals("Output present", false, output.isPresent());
+
+        final ArgumentCaptor<NormalizedNode> capturedNode = ArgumentCaptor.forClass(NormalizedNode.class);
+        verify(mockRpcService).invokeRpc(eq(path), capturedNode.capture());
+
+        assertTrue("Expected ContainerNode. Actual " + capturedNode.getValue().getClass(),
+                capturedNode.getValue() instanceof ContainerNode);
+        final ContainerNode actualNode = (ContainerNode) capturedNode.getValue();
+        verifyLeafNode(actualNode, TOASTER_DONENESS_QNAME, Long.valueOf(10));
+        verifyLeafNode(actualNode, TOASTER_TYPE_QNAME, WHEAT_BREAD_QNAME);
+    }
+
+    @Test
+    public void testInvokeRpcWithNoInput() throws Exception {
+        final SchemaPath path = SchemaPath.create(true, CANCEL_TOAST_QNAME);
+
+        final DOMRpcResult expResult = new DefaultDOMRpcResult((NormalizedNode<?, ?>)null);
+        doReturn(Futures.immediateCheckedFuture(expResult)).when(mockRpcService).invokeRpc(eq(path),
+                any(NormalizedNode.class));
+
+        final String uriPath = "toaster:cancel-toast";
+
+        final Optional<String> output = this.service.invokeRpc(uriPath, Optional.<String>absent());
+
+        assertEquals("Output present", false, output.isPresent());
+
+        verify(mockRpcService).invokeRpc(eq(path), isNull(NormalizedNode.class));
+    }
+
+    @Test
+    public void testInvokeRpcWithOutput() throws Exception {
+        final SchemaPath path = SchemaPath.create(true, TEST_OUTPUT_QNAME);
+
+        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(Futures.immediateCheckedFuture(expResult)).when(mockRpcService).invokeRpc(eq(path),
+                any(NormalizedNode.class));
+
+        final String uriPath = "toaster:testOutput";
+
+        final Optional<String> output = this.service.invokeRpc(uriPath, Optional.<String>absent());
+
+        assertEquals("Output present", true, output.isPresent());
+        assertNotNull("Returned null response", output.get());
+        assertThat("Missing \"textOut\"", output.get(), containsString("\"textOut\":\"foo\""));
+
+        verify(mockRpcService).invokeRpc(eq(path), isNull(NormalizedNode.class));
+    }
+
+    @Test(expected = OperationFailedException.class)
+    public void testInvokeRpcFailure() throws Exception {
+        final DOMRpcException exception = new DOMRpcImplementationNotAvailableException("testExeption");
+        doReturn(Futures.immediateFailedCheckedFuture(exception)).when(mockRpcService).invokeRpc(any(SchemaPath.class),
+                any(NormalizedNode.class));
+
+        final String uriPath = "toaster:cancel-toast";
+
+        this.service.invokeRpc(uriPath, Optional.<String>absent());
+    }
+
+    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();
+
+        doReturn(Futures.immediateCheckedFuture(Optional.of(entryNode))).when(mockReadOnlyTx).read(
+                eq(datastoreType), any(YangInstanceIdentifier.class));
+
+        final String uriPath = "ietf-interfaces:interfaces/interface=eth0";
+
+        final Optional<String> optionalResp = this.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);
+        verify(mockReadOnlyTx).read(eq(datastoreType), capturedPath.capture());
+
+        verifyPath(capturedPath.getValue(), INTERFACES_QNAME, INTERFACE_QNAME,
+                new Object[]{INTERFACE_QNAME, NAME_QNAME, "eth0"});
+    }
+
+    DOMMountPoint setupTestMountPoint() throws FileNotFoundException, ReactorException {
+        final SchemaContext schemaContextTestModule = TestUtils.loadSchemaContext("/full-versions/test-module");
+        final DOMMountPoint mockMountPoint = mock(DOMMountPoint.class);
+        doReturn(schemaContextTestModule).when(mockMountPoint).getSchemaContext();
+
+        doReturn(Optional.of(mockDOMDataBroker)).when(mockMountPoint).getService(DOMDataBroker.class);
+
+        doReturn(Optional.of(mockMountPoint))
+                .when(mockMountPointService).getMountPoint(notNull(YangInstanceIdentifier.class));
+
+        return mockMountPoint;
+    }
+
+    void verifyLeafNode(final DataContainerNode<?> parent, final QName leafType, final Object leafValue) {
+        final Optional<DataContainerChild<?, ?>> leafChild = parent.getChild(new NodeIdentifier(leafType));
+        assertEquals(leafType.toString() + " present", true, leafChild.isPresent());
+        assertEquals(leafType.toString() + " value", leafValue, leafChild.get().getValue());
+    }
+
+    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 Map<QName, Object> keyValues = ((NodeIdentifierWithPredicates)actual).getKeyValues();
+                assertEquals(String.format("Path arg %d keyValues size", index + 1), 1, keyValues.size());
+                final QName expKey = (QName) listEntry[1];
+                assertEquals(String.format("Path arg %d keyValue for %s", index + 1, expKey), listEntry[2],
+                        keyValues.get(expKey));
+            } else {
+                expNodeType = (QName) expArgs[index];
+            }
+
+            assertEquals(String.format("Path arg %d node type", index + 1), expNodeType, actual.getNodeType());
+            index++;
+        }
+
+    }
+}
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/make-toast-rpc-input.json b/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/make-toast-rpc-input.json
new file mode 100644 (file)
index 0000000..50d2a7c
--- /dev/null
@@ -0,0 +1,7 @@
+{
+    "input" :
+    {
+     "toaster:toasterDoneness" : "10",
+     "toaster:toasterToastType": "wheat-bread"
+    }
+}
\ No newline at end of file
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data-rpc-input.json b/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data-rpc-input.json
new file mode 100644 (file)
index 0000000..0eae37a
--- /dev/null
@@ -0,0 +1,10 @@
+{
+    "test-module:input":{
+        "cont":{
+            "cont1":{
+                "lf11":"lf1 data",
+                "lf12":"lf2 data"
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data-rpc-input.xml b/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data-rpc-input.xml
new file mode 100644 (file)
index 0000000..fb9726d
--- /dev/null
@@ -0,0 +1,8 @@
+<input xmlns="test:module">
+    <cont>
+        <cont1>
+            <lf11>lf1 data</lf11>
+            <lf12>lf2 data</lf12>
+        </cont1>
+    </cont>
+</input>
\ No newline at end of file
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data2.xml b/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data2.xml
new file mode 100644 (file)
index 0000000..db2f4e9
--- /dev/null
@@ -0,0 +1,6 @@
+<cont xmlns="test:module">
+    <cont1>
+        <lf11>lf1 data</lf11>
+        <lf12>lf2 data</lf12>
+    </cont1>
+</cont>
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data3.xml b/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data3.xml
new file mode 100644 (file)
index 0000000..b7b05d1
--- /dev/null
@@ -0,0 +1,4 @@
+<cont1 xmlns="test:module">
+ <lf11>lf1 data</lf11>
+ <lf12>lf2 data</lf12>
+</cont1>
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data4.xml b/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data4.xml
new file mode 100644 (file)
index 0000000..3ce6741
--- /dev/null
@@ -0,0 +1,6 @@
+
+<cont1 xmlns="test:module">
+    <lf11>lf1 data</lf11>
+    <lf12>lf2 data</lf12>
+</cont1>
+
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data5.xml b/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data5.xml
new file mode 100644 (file)
index 0000000..89aa782
--- /dev/null
@@ -0,0 +1,8 @@
+<interfaces xmlns="test:module">
+    <class>
+        <name>John</name>
+        <address>F.C.I 43</address>
+        <email>j@j</email>
+    </class>
+</interfaces>
+
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data6.xml b/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data6.xml
new file mode 100644 (file)
index 0000000..7feb6bf
--- /dev/null
@@ -0,0 +1,6 @@
+<class xmlns="test:module">
+    <name>John</name>
+    <address>F.C.I 43</address>
+    <email>j@j</email>
+</class>
+
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data7.xml b/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-data2/data7.xml
new file mode 100644 (file)
index 0000000..4374277
--- /dev/null
@@ -0,0 +1,8 @@
+<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
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-module/test-module.yang b/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/test-module/test-module.yang
new file mode 100644 (file)
index 0000000..34c450c
--- /dev/null
@@ -0,0 +1,101 @@
+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
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/testCont1Data.json b/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/testCont1Data.json
new file mode 100644 (file)
index 0000000..c7554f7
--- /dev/null
@@ -0,0 +1,6 @@
+{
+    "cont1": {
+        "lf11": "lf11 data",
+        "lf12": "lf12 data"
+    }
+}
\ No newline at end of file
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/testData.json b/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/testData.json
new file mode 100644 (file)
index 0000000..a736067
--- /dev/null
@@ -0,0 +1,92 @@
+{
+  "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
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/testData.xml b/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/testData.xml
new file mode 100644 (file)
index 0000000..bdd9c10
--- /dev/null
@@ -0,0 +1,120 @@
+<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
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/ex-vlan.yang b/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/ex-vlan.yang
new file mode 100644 (file)
index 0000000..e34c494
--- /dev/null
@@ -0,0 +1,47 @@
+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
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/iana-if-type.yang b/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/iana-if-type.yang
new file mode 100644 (file)
index 0000000..7bd0003
--- /dev/null
@@ -0,0 +1,1517 @@
+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
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/ietf-interfaces@2013-07-04.yang b/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/ietf-interfaces@2013-07-04.yang
new file mode 100644 (file)
index 0000000..9db753c
--- /dev/null
@@ -0,0 +1,673 @@
+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
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/ietf-yang-types@2013-05-16.yang b/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/ietf-yang-types@2013-05-16.yang
new file mode 100644 (file)
index 0000000..6c82d9d
--- /dev/null
@@ -0,0 +1,471 @@
+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
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/sal-remote@2014-01-14.yang b/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/sal-remote@2014-01-14.yang
new file mode 100644 (file)
index 0000000..e51f870
--- /dev/null
@@ -0,0 +1,97 @@
+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
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/simple-nodes.yang b/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/simple-nodes.yang
new file mode 100644 (file)
index 0000000..00156f7
--- /dev/null
@@ -0,0 +1,74 @@
+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 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;
+                   }
+               }
+           }
+       }
+    }
+}
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/subscribe-to-notification.yang b/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/subscribe-to-notification.yang
new file mode 100644 (file)
index 0000000..5fe7df7
--- /dev/null
@@ -0,0 +1,18 @@
+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;
+        }
+    }
+}
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/toaster.yang b/restconf/restconf-nb-rfc8040/src/test/resources/full-versions/yangs/toaster.yang
new file mode 100644 (file)
index 0000000..9ae9770
--- /dev/null
@@ -0,0 +1,197 @@
+  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
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/parts/ietf-interfaces_interfaces.json b/restconf/restconf-nb-rfc8040/src/test/resources/parts/ietf-interfaces_interfaces.json
new file mode 100644 (file)
index 0000000..0b39dc7
--- /dev/null
@@ -0,0 +1,10 @@
+{
+    "interface":[
+        {
+            "name":"eth0",
+            "type":"ethernetCsmacd",
+            "enabled":false,
+            "description": "some interface"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/parts/ietf-interfaces_interfaces.xml b/restconf/restconf-nb-rfc8040/src/test/resources/parts/ietf-interfaces_interfaces.xml
new file mode 100644 (file)
index 0000000..19569b5
--- /dev/null
@@ -0,0 +1,6 @@
+<interface xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
+  <name>eth0</name>
+  <type>ethernetCsmacd</type>
+  <enabled>false</enabled>
+  <description>some interface</description>
+</interface>
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/parts/ietf-interfaces_interfaces2.xml b/restconf/restconf-nb-rfc8040/src/test/resources/parts/ietf-interfaces_interfaces2.xml
new file mode 100644 (file)
index 0000000..b4bdec8
--- /dev/null
@@ -0,0 +1,5 @@
+<class xmlns="test:module">
+    <name>xxx</name>
+    <address>bbb</address>
+    <email>ccc</email>
+</class>
\ No newline at end of file
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/parts/ietf-interfaces_interfaces_absolute_path.json b/restconf/restconf-nb-rfc8040/src/test/resources/parts/ietf-interfaces_interfaces_absolute_path.json
new file mode 100644 (file)
index 0000000..7de7fac
--- /dev/null
@@ -0,0 +1,12 @@
+{
+    "ietf-interfaces:interfaces":{
+        "interface":[
+            {
+                "name":"eth0",
+                "type":"ethernetCsmacd",
+                "enabled":false,
+                "description": "some interface"
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/parts/ietf-interfaces_interfaces_absolute_path.xml b/restconf/restconf-nb-rfc8040/src/test/resources/parts/ietf-interfaces_interfaces_absolute_path.xml
new file mode 100644 (file)
index 0000000..313f32d
--- /dev/null
@@ -0,0 +1,8 @@
+<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
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/parts/ietf-interfaces_interfaces_absolute_path2.xml b/restconf/restconf-nb-rfc8040/src/test/resources/parts/ietf-interfaces_interfaces_absolute_path2.xml
new file mode 100644 (file)
index 0000000..77cb026
--- /dev/null
@@ -0,0 +1,7 @@
+
+<interface xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
+    <name>eth0</name>
+    <type>ethernetCsmacd</type>
+    <enabled>false</enabled>
+    <description>some interface</description>
+</interface>
diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/parts/ietf-interfaces_interfaces_interface_absolute_path.xml b/restconf/restconf-nb-rfc8040/src/test/resources/parts/ietf-interfaces_interfaces_interface_absolute_path.xml
new file mode 100644 (file)
index 0000000..19569b5
--- /dev/null
@@ -0,0 +1,6 @@
+<interface xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
+  <name>eth0</name>
+  <type>ethernetCsmacd</type>
+  <enabled>false</enabled>
+  <description>some interface</description>
+</interface>