BUG-997 Consult QNames of yang modules with ietf-netconf-monitoring/netconf-state... 84/9484/4
authorMaros Marsalek <mmarsale@cisco.com>
Tue, 29 Jul 2014 15:06:44 +0000 (17:06 +0200)
committerMaros Marsalek <mmarsale@cisco.com>
Thu, 7 Aug 2014 06:36:35 +0000 (08:36 +0200)
Change-Id: Ie0fcb6d9ba44207cb14d31d51c1f3068983d514e
Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemas.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCommunicator.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceReadOnlyTx.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NetconfMessageTransformUtil.java
opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java
opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemasTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/test/resources/netconf-state.schemas.payload.xml [new file with mode: 0644]

index 07d3c08..350132c 100644 (file)
@@ -7,17 +7,11 @@
  */
 package org.opendaylight.controller.sal.connect.netconf;
 
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
 import java.io.InputStream;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.ExecutorService;
+
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.controller.sal.connect.api.MessageTransformer;
@@ -40,6 +34,14 @@ import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
 /**
  *  This is a mediator between NetconfDeviceCommunicator and NetconfDeviceSalFacade
  */
@@ -54,11 +56,20 @@ public final class NetconfDevice implements RemoteDevice<NetconfSessionCapabilit
     private final MessageTransformer<NetconfMessage> messageTransformer;
     private final SchemaContextProviderFactory schemaContextProviderFactory;
     private final SchemaSourceProviderFactory<InputStream> sourceProviderFactory;
+    private final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver;
     private final NotificationHandler notificationHandler;
 
     public static NetconfDevice createNetconfDevice(final RemoteDeviceId id,
             final AbstractCachingSchemaSourceProvider<String, InputStream> schemaSourceProvider,
             final ExecutorService executor, final RemoteDeviceHandler<NetconfSessionCapabilities> salFacade) {
+        return createNetconfDevice(id, schemaSourceProvider, executor, salFacade, new NetconfStateSchemas.NetconfStateSchemasResolverImpl());
+    }
+
+    @VisibleForTesting
+    protected static NetconfDevice createNetconfDevice(final RemoteDeviceId id,
+            final AbstractCachingSchemaSourceProvider<String, InputStream> schemaSourceProvider,
+            final ExecutorService executor, final RemoteDeviceHandler<NetconfSessionCapabilities> salFacade,
+            final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver) {
 
         return new NetconfDevice(id, salFacade, executor, new NetconfMessageTransformer(),
                 new NetconfDeviceSchemaProviderFactory(id), new SchemaSourceProviderFactory<InputStream>() {
@@ -67,18 +78,20 @@ public final class NetconfDevice implements RemoteDevice<NetconfSessionCapabilit
                         return schemaSourceProvider.createInstanceFor(new NetconfRemoteSchemaSourceProvider(id,
                                 deviceRpc));
                     }
-                });
+                }, stateSchemasResolver);
     }
 
     @VisibleForTesting
     protected NetconfDevice(final RemoteDeviceId id, final RemoteDeviceHandler<NetconfSessionCapabilities> salFacade,
-            final ExecutorService processingExecutor, final MessageTransformer<NetconfMessage> messageTransformer,
-            final SchemaContextProviderFactory schemaContextProviderFactory,
-            final SchemaSourceProviderFactory<InputStream> sourceProviderFactory) {
+                            final ExecutorService processingExecutor, final MessageTransformer<NetconfMessage> messageTransformer,
+                            final SchemaContextProviderFactory schemaContextProviderFactory,
+                            final SchemaSourceProviderFactory<InputStream> sourceProviderFactory,
+                            final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver) {
         this.id = id;
         this.messageTransformer = messageTransformer;
         this.salFacade = salFacade;
         this.sourceProviderFactory = sourceProviderFactory;
+        this.stateSchemasResolver = stateSchemasResolver;
         this.processingExecutor = MoreExecutors.listeningDecorator(processingExecutor);
         this.schemaContextProviderFactory = schemaContextProviderFactory;
         this.notificationHandler = new NotificationHandler(salFacade, messageTransformer, id);
@@ -98,6 +111,11 @@ public final class NetconfDevice implements RemoteDevice<NetconfSessionCapabilit
             @Override
             public void run() {
                 final NetconfDeviceRpc deviceRpc = setUpDeviceRpc(remoteSessionCapabilities, listener);
+
+                final NetconfStateSchemas availableSchemas = stateSchemasResolver.resolve(deviceRpc, remoteSessionCapabilities, id);
+                logger.warn("{}: Schemas exposed by ietf-netconf-monitoring: {}", id, availableSchemas.getAvailableYangSchemasQNames());
+                // TODO use this for shared schema context
+
                 final SchemaSourceProvider<InputStream> delegate = sourceProviderFactory.createSourceProvider(deviceRpc);
                 final SchemaContextProvider schemaContextProvider = setUpSchemaContext(delegate, remoteSessionCapabilities);
                 updateMessageTransformer(schemaContextProvider);
@@ -204,6 +222,6 @@ public final class NetconfDevice implements RemoteDevice<NetconfSessionCapabilit
             Preconditions.checkNotNull(parsedNotification);
             salFacade.onNotification(parsedNotification);
         }
-
     }
+
 }
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemas.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemas.java
new file mode 100644 (file)
index 0000000..b540034
--- /dev/null
@@ -0,0 +1,213 @@
+package org.opendaylight.controller.sal.connect.netconf;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import java.net.URI;
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionCapabilities;
+import org.opendaylight.controller.sal.connect.netconf.sal.NetconfDeviceRpc;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.Yang;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Holds QNames for all yang modules reported by ietf-netconf-monitoring/state/schemas
+ */
+public final class NetconfStateSchemas {
+
+    private static final Logger logger = LoggerFactory.getLogger(NetconfStateSchemas.class);
+
+    /**
+     * Factory for NetconfStateSchemas
+     */
+    public interface NetconfStateSchemasResolver {
+        NetconfStateSchemas resolve(final NetconfDeviceRpc deviceRpc, final NetconfSessionCapabilities remoteSessionCapabilities, final RemoteDeviceId id);
+    }
+
+    /**
+     * Default implementation resolving schemas QNames from netconf-state
+     */
+    public static final class NetconfStateSchemasResolverImpl implements NetconfStateSchemasResolver {
+
+        @Override
+        public NetconfStateSchemas resolve(final NetconfDeviceRpc deviceRpc, final NetconfSessionCapabilities remoteSessionCapabilities, final RemoteDeviceId id) {
+            return NetconfStateSchemas.create(deviceRpc, remoteSessionCapabilities, id);
+        }
+    }
+
+    public static final NetconfStateSchemas EMPTY = new NetconfStateSchemas(Collections.<RemoteYangSchema>emptySet());
+
+    private static final YangInstanceIdentifier STATE_SCHEMAS_IDENTIFIER =
+            YangInstanceIdentifier.builder().node(NetconfState.QNAME).node(Schemas.QNAME).build();
+    private static final YangInstanceIdentifier DATA_STATE_SCHEMAS_IDENTIFIER =
+            YangInstanceIdentifier.builder().node(NetconfMessageTransformUtil.NETCONF_DATA_QNAME)
+                    .node(NetconfState.QNAME).node(Schemas.QNAME).build();
+
+    private static final CompositeNode GET_SCHEMAS_RPC;
+    static {
+        final Node<?> filter = NetconfMessageTransformUtil.toFilterStructure(STATE_SCHEMAS_IDENTIFIER);
+        GET_SCHEMAS_RPC
+                = NodeFactory.createImmutableCompositeNode(NetconfMessageTransformUtil.NETCONF_GET_QNAME, null, Lists.<Node<?>>newArrayList(filter));
+    }
+
+    private final Set<RemoteYangSchema> availableYangSchemas;
+
+    public NetconfStateSchemas(final Set<RemoteYangSchema> availableYangSchemas) {
+        this.availableYangSchemas = availableYangSchemas;
+    }
+
+    public Set<RemoteYangSchema> getAvailableYangSchemas() {
+        return availableYangSchemas;
+    }
+
+    public Set<QName> getAvailableYangSchemasQNames() {
+        return Sets.newHashSet(Collections2.transform(getAvailableYangSchemas(), new Function<RemoteYangSchema, QName>() {
+            @Override
+            public QName apply(final RemoteYangSchema input) {
+                return input.getQName();
+            }
+        }));
+    }
+
+    /**
+     * Issue get request to remote device and parse response to find all schemas under netconf-state/schemas
+     */
+    private static NetconfStateSchemas create(final NetconfDeviceRpc deviceRpc, final NetconfSessionCapabilities remoteSessionCapabilities, final RemoteDeviceId id) {
+        if(remoteSessionCapabilities.isMonitoringSupported() == false) {
+            logger.warn("{}: Netconf monitoring not supported on device, cannot detect available schemas");
+            return EMPTY;
+        }
+
+        final RpcResult<CompositeNode> schemasNodeResult;
+        try {
+            schemasNodeResult = deviceRpc.invokeRpc(NetconfMessageTransformUtil.NETCONF_GET_QNAME, GET_SCHEMAS_RPC).get();
+        } catch (final InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new RuntimeException(id + ": Interrupted while waiting for response to " + STATE_SCHEMAS_IDENTIFIER, e);
+        } catch (final ExecutionException e) {
+            logger.warn("{}: Unable to detect available schemas, get to {} failed", id, STATE_SCHEMAS_IDENTIFIER, e);
+            return EMPTY;
+        }
+
+        if(schemasNodeResult.isSuccessful() == false) {
+            logger.warn("{}: Unable to detect available schemas, get to {} failed, {}", id, STATE_SCHEMAS_IDENTIFIER, schemasNodeResult.getErrors());
+            return EMPTY;
+        }
+
+        final CompositeNode schemasNode =
+                (CompositeNode) NetconfMessageTransformUtil.findNode(schemasNodeResult.getResult(), DATA_STATE_SCHEMAS_IDENTIFIER);
+        return create(schemasNode);
+    }
+
+    /**
+     * Parse response of get(netconf-state/schemas) to find all schemas under netconf-state/schemas
+     */
+    @VisibleForTesting
+    protected static NetconfStateSchemas create(final CompositeNode schemasNode) {
+        final Set<RemoteYangSchema> availableYangSchemas = Sets.newHashSet();
+
+        for (final CompositeNode schemaNode : schemasNode.getCompositesByName(Schema.QNAME.withoutRevision())) {
+            availableYangSchemas.add(RemoteYangSchema.createFromCompositeNode(schemaNode));
+        }
+
+        return new NetconfStateSchemas(availableYangSchemas);
+    }
+
+    public final static class RemoteYangSchema {
+        private final QName qname;
+
+        private RemoteYangSchema(final QName qname) {
+            this.qname = qname;
+        }
+
+        public QName getQName() {
+            return qname;
+        }
+
+        static RemoteYangSchema createFromCompositeNode(final CompositeNode schemaNode) {
+            Preconditions.checkArgument(schemaNode.getKey().equals(Schema.QNAME.withoutRevision()), "Wrong QName %s", schemaNode.getKey());
+
+            QName childNode = NetconfMessageTransformUtil.IETF_NETCONF_MONITORING_SCHEMA_FORMAT.withoutRevision();
+
+            final String formatAsString = getSingleChildNodeValue(schemaNode, childNode).get();
+            Preconditions.checkArgument(formatAsString.equals(Yang.QNAME.getLocalName()),
+                    "Expecting format to be only %s, not %s", Yang.QNAME.getLocalName(), formatAsString);
+
+            childNode = NetconfMessageTransformUtil.IETF_NETCONF_MONITORING_SCHEMA_LOCATION.withoutRevision();
+            final Set<String> locationsAsString = getAllChildNodeValues(schemaNode, childNode);
+            Preconditions.checkArgument(locationsAsString.contains(Schema.Location.Enumeration.NETCONF.toString()),
+                    "Expecting location to be %s, not %s", Schema.Location.Enumeration.NETCONF.toString(), locationsAsString);
+
+            childNode = NetconfMessageTransformUtil.IETF_NETCONF_MONITORING_SCHEMA_NAMESPACE.withoutRevision();
+            final String namespaceAsString = getSingleChildNodeValue(schemaNode, childNode).get();
+
+            childNode = NetconfMessageTransformUtil.IETF_NETCONF_MONITORING_SCHEMA_VERSION.withoutRevision();
+            // Revision does not have to be filled
+            final Optional<String> revisionAsString = getSingleChildNodeValue(schemaNode, childNode);
+
+            childNode = NetconfMessageTransformUtil.IETF_NETCONF_MONITORING_SCHEMA_IDENTIFIER.withoutRevision();
+            final String moduleNameAsString = getSingleChildNodeValue(schemaNode, childNode).get();
+
+            final QName moduleQName = revisionAsString.isPresent()
+                    ? QName.create(namespaceAsString, revisionAsString.get(), moduleNameAsString)
+                    : QName.create(URI.create(namespaceAsString), null, moduleNameAsString).withoutRevision();
+
+            return new RemoteYangSchema(moduleQName);
+        }
+
+        private static Set<String> getAllChildNodeValues(final CompositeNode schemaNode, final QName childNodeQName) {
+            final Set<String> extractedValues = Sets.newHashSet();
+            for (final SimpleNode<?> childNode : schemaNode.getSimpleNodesByName(childNodeQName)) {
+                extractedValues.add(getValueOfSimpleNode(childNodeQName, childNode).get());
+            }
+            return extractedValues;
+        }
+
+        private static Optional<String> getSingleChildNodeValue(final CompositeNode schemaNode, final QName childNode) {
+            final SimpleNode<?> node = schemaNode.getFirstSimpleByName(childNode);
+            return getValueOfSimpleNode(childNode, node);
+        }
+
+        private static Optional<String> getValueOfSimpleNode(final QName childNode, final SimpleNode<?> node) {
+            Preconditions.checkNotNull(node, "Child node %s not present", childNode);
+            final Object value = node.getValue();
+            return value == null ? Optional.<String>absent() : Optional.of(value.toString().trim());
+        }
+
+        @Override
+        public boolean equals(final Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            final RemoteYangSchema that = (RemoteYangSchema) o;
+
+            if (!qname.equals(that.qname)) return false;
+
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            return qname.hashCode();
+        }
+    }
+}
index 3871cdf..2f24adc 100644 (file)
@@ -229,7 +229,7 @@ public class NetconfDeviceCommunicator implements NetconfClientSessionListener,
             try {
                 NetconfMessageTransformUtil.checkSuccessReply(message);
             }
-            catch( NetconfDocumentedException e ) {
+            catch(final NetconfDocumentedException e) {
                 logger.warn( "{}: Error reply from remote device, request: {}, response: {}", id,
                              msgToS( request.request ), msgToS( message ), e );
 
index 533df9c..04a9951 100644 (file)
@@ -30,8 +30,6 @@ import org.opendaylight.controller.sal.core.api.RpcImplementation;
 import org.opendaylight.yangtools.util.concurrent.MappingCheckedFuture;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.api.SimpleNode;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.slf4j.Logger;
@@ -63,7 +61,7 @@ public final class NetconfDeviceReadOnlyTx implements DOMDataReadOnlyTransaction
                 checkReadSuccess(result, path);
 
                 final CompositeNode data = result.getResult().getFirstCompositeByName(NETCONF_DATA_QNAME);
-                final CompositeNode node = (CompositeNode) findNode(data, path);
+                final CompositeNode node = (CompositeNode) NetconfMessageTransformUtil.findNode(data, path);
 
                 return data == null ?
                         Optional.<NormalizedNode<?, ?>>absent() :
@@ -105,7 +103,7 @@ public final class NetconfDeviceReadOnlyTx implements DOMDataReadOnlyTransaction
                 checkReadSuccess(result, path);
 
                 final CompositeNode data = result.getResult().getFirstCompositeByName(NETCONF_DATA_QNAME);
-                final CompositeNode node = (CompositeNode) findNode(data, path);
+                final CompositeNode node = (CompositeNode) NetconfMessageTransformUtil.findNode(data, path);
 
                 return data == null ?
                         Optional.<NormalizedNode<?, ?>>absent() :
@@ -116,33 +114,6 @@ public final class NetconfDeviceReadOnlyTx implements DOMDataReadOnlyTransaction
         return MappingCheckedFuture.create(transformedFuture, ReadFailedException.MAPPER);
     }
 
-    private static Node<?> findNode(final CompositeNode node, final YangInstanceIdentifier identifier) {
-
-        Node<?> current = node;
-        for (final YangInstanceIdentifier.PathArgument arg : identifier.getPathArguments()) {
-            if (current instanceof SimpleNode<?>) {
-                return null;
-            } else if (current instanceof CompositeNode) {
-                final CompositeNode currentComposite = (CompositeNode) current;
-
-                current = currentComposite.getFirstCompositeByName(arg.getNodeType());
-                if (current == null) {
-                    current = currentComposite.getFirstCompositeByName(arg.getNodeType().withoutRevision());
-                }
-                if (current == null) {
-                    current = currentComposite.getFirstSimpleByName(arg.getNodeType());
-                }
-                if (current == null) {
-                    current = currentComposite.getFirstSimpleByName(arg.getNodeType().withoutRevision());
-                }
-                if (current == null) {
-                    return null;
-                }
-            }
-        }
-        return current;
-    }
-
     @Override
     public void close() {
         // NOOP
index 47ef903..5e61dfb 100644 (file)
@@ -96,7 +96,7 @@ public class NetconfMessageTransformer implements MessageTransformer<NetconfMess
             return toRpcResult(message, rpc, schemaContext.get());
         } else {
             final CompositeNode node = (CompositeNode) XmlDocumentUtils.toDomNode(message.getDocument());
-            return RpcResultBuilder.success( node ).build();
+            return RpcResultBuilder.success(node).build();
         }
     }
 
index 4f792a0..1e3cf4b 100644 (file)
@@ -27,6 +27,7 @@ import javax.annotation.Nullable;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity;
@@ -34,6 +35,7 @@ import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
 import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
 import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
@@ -49,7 +51,13 @@ public class NetconfMessageTransformUtil {
 
     private NetconfMessageTransformUtil() {}
 
-    public static final QName IETF_NETCONF_MONITORING = QName.create("urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring", "2010-10-04", "ietf-netconf-monitoring");
+    public static final QName IETF_NETCONF_MONITORING = QName.create(NetconfState.QNAME, "ietf-netconf-monitoring");
+    public static final QName IETF_NETCONF_MONITORING_SCHEMA_FORMAT = QName.create(IETF_NETCONF_MONITORING, "format");
+    public static final QName IETF_NETCONF_MONITORING_SCHEMA_LOCATION = QName.create(IETF_NETCONF_MONITORING, "location");
+    public static final QName IETF_NETCONF_MONITORING_SCHEMA_IDENTIFIER = QName.create(IETF_NETCONF_MONITORING, "identifier");
+    public static final QName IETF_NETCONF_MONITORING_SCHEMA_VERSION = QName.create(IETF_NETCONF_MONITORING, "version");
+    public static final QName IETF_NETCONF_MONITORING_SCHEMA_NAMESPACE = QName.create(IETF_NETCONF_MONITORING, "namespace");
+
     public static URI NETCONF_URI = URI.create("urn:ietf:params:xml:ns:netconf:base:1.0");
     public static QName NETCONF_QNAME = QName.create(NETCONF_URI, null, "netconf");
     public static QName NETCONF_DATA_QNAME = QName.create(NETCONF_QNAME, "data");
@@ -365,4 +373,31 @@ public class NetconfMessageTransformUtil {
             return it.toInstance();
         }
     }
+
+    public static Node<?> findNode(final CompositeNode node, final YangInstanceIdentifier identifier) {
+
+        Node<?> current = node;
+        for (final YangInstanceIdentifier.PathArgument arg : identifier.getPathArguments()) {
+            if (current instanceof SimpleNode<?>) {
+                return null;
+            } else if (current instanceof CompositeNode) {
+                final CompositeNode currentComposite = (CompositeNode) current;
+
+                current = currentComposite.getFirstCompositeByName(arg.getNodeType());
+                if (current == null) {
+                    current = currentComposite.getFirstCompositeByName(arg.getNodeType().withoutRevision());
+                }
+                if (current == null) {
+                    current = currentComposite.getFirstSimpleByName(arg.getNodeType());
+                }
+                if (current == null) {
+                    current = currentComposite.getFirstSimpleByName(arg.getNodeType().withoutRevision());
+                }
+                if (current == null) {
+                    return null;
+                }
+            }
+        }
+        return current;
+    }
 }
index 46ea4ff..fa488da 100644 (file)
@@ -15,6 +15,9 @@ import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.Futures;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -23,7 +26,6 @@ import java.util.List;
 import java.util.Set;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
-
 import org.junit.Test;
 import org.mockito.Mockito;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
@@ -34,6 +36,7 @@ import org.opendaylight.controller.sal.connect.api.RemoteDeviceHandler;
 import org.opendaylight.controller.sal.connect.api.SchemaContextProviderFactory;
 import org.opendaylight.controller.sal.connect.api.SchemaSourceProviderFactory;
 import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionCapabilities;
+import org.opendaylight.controller.sal.connect.netconf.sal.NetconfDeviceRpc;
 import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
 import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
 import org.opendaylight.controller.sal.core.api.RpcImplementation;
@@ -47,10 +50,6 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
 import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
 
-import com.google.common.base.Optional;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.Futures;
-
 public class NetconfDeviceTest {
 
     private static final NetconfMessage netconfMessage;
@@ -71,13 +70,20 @@ public class NetconfDeviceTest {
     public static final String TEST_NAMESPACE = "test:namespace";
     public static final String TEST_MODULE = "test-module";
     public static final String TEST_REVISION = "2013-07-22";
+    private NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver = new NetconfStateSchemas.NetconfStateSchemasResolver() {
+
+        @Override
+        public NetconfStateSchemas resolve(final NetconfDeviceRpc deviceRpc, final NetconfSessionCapabilities remoteSessionCapabilities, final RemoteDeviceId id) {
+            return NetconfStateSchemas.EMPTY;
+        }
+    };
 
     @Test
     public void testNetconfDeviceWithoutMonitoring() throws Exception {
         final RemoteDeviceHandler<NetconfSessionCapabilities> facade = getFacade();
         final RemoteDeviceCommunicator<NetconfMessage> listener = getListener();
 
-        final NetconfDevice device = new NetconfDevice(getId(), facade, getExecutor(), getMessageTransformer(), getSchemaContextProviderFactory(), getSourceProviderFactory());
+        final NetconfDevice device = new NetconfDevice(getId(), facade, getExecutor(), getMessageTransformer(), getSchemaContextProviderFactory(), getSourceProviderFactory(), stateSchemasResolver);
         device.onRemoteSessionUp(getSessionCaps(false, Collections.<String>emptyList()), listener);
 
         Mockito.verify(facade, Mockito.timeout(5000)).onDeviceDisconnected();
@@ -89,7 +95,7 @@ public class NetconfDeviceTest {
         final RemoteDeviceCommunicator<NetconfMessage> listener = getListener();
 
         final MessageTransformer<NetconfMessage> messageTransformer = getMessageTransformer();
-        final NetconfDevice device = new NetconfDevice(getId(), facade, getExecutor(), messageTransformer, getSchemaContextProviderFactory(), getSourceProviderFactory());
+        final NetconfDevice device = new NetconfDevice(getId(), facade, getExecutor(), messageTransformer, getSchemaContextProviderFactory(), getSourceProviderFactory(), stateSchemasResolver);
 
         device.onNotification(netconfMessage);
         device.onNotification(netconfMessage);
@@ -118,7 +124,7 @@ public class NetconfDeviceTest {
         final SchemaSourceProviderFactory<InputStream> sourceProviderFactory = getSourceProviderFactory();
         final MessageTransformer<NetconfMessage> messageTransformer = getMessageTransformer();
 
-        final NetconfDevice device = new NetconfDevice(getId(), facade, getExecutor(), messageTransformer, schemaContextProviderFactory, sourceProviderFactory);
+        final NetconfDevice device = new NetconfDevice(getId(), facade, getExecutor(), messageTransformer, schemaContextProviderFactory, sourceProviderFactory, stateSchemasResolver);
         final NetconfSessionCapabilities sessionCaps = getSessionCaps(true,
                 Lists.newArrayList(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&amp;revision=" + TEST_REVISION));
         device.onRemoteSessionUp(sessionCaps, listener);
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemasTest.java b/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemasTest.java
new file mode 100644 (file)
index 0000000..16a915e
--- /dev/null
@@ -0,0 +1,29 @@
+package org.opendaylight.controller.sal.connect.netconf;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.matchers.JUnitMatchers.hasItem;
+
+import java.util.Set;
+import org.junit.Test;
+import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils;
+import org.w3c.dom.Document;
+
+public class NetconfStateSchemasTest {
+
+    @Test
+    public void testCreate() throws Exception {
+        final Document schemasXml = XmlUtil.readXmlToDocument(getClass().getResourceAsStream("/netconf-state.schemas.payload.xml"));
+        final CompositeNode compositeNodeSchemas = (CompositeNode) XmlDocumentUtils.toDomNode(schemasXml);
+        final NetconfStateSchemas schemas = NetconfStateSchemas.create(compositeNodeSchemas);
+
+        final Set<QName> availableYangSchemasQNames = schemas.getAvailableYangSchemasQNames();
+        assertEquals(73, availableYangSchemasQNames.size());
+
+        assertThat(availableYangSchemasQNames,
+                hasItem(QName.create("urn:TBD:params:xml:ns:yang:network-topology", "2013-07-12", "network-topology")));
+    }
+}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/test/resources/netconf-state.schemas.payload.xml b/opendaylight/md-sal/sal-netconf-connector/src/test/resources/netconf-state.schemas.payload.xml
new file mode 100644 (file)
index 0000000..649ecb7
--- /dev/null
@@ -0,0 +1,514 @@
+<ncm:schemas xmlns:ncm="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:threadpool</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>threadpool</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-04-09</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:logback:config</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>config-logging</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-07-16</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:model:statistics:types</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-statistics-types</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-09-25</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:config-dom-store</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-config-dom-datastore</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2014-06-17</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:flow:table:statistics</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-flow-table-statistics</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-12-15</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:meter:service</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>sal-meter</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-09-18</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>toaster-provider-impl</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2014-01-31</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:table:types</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-table-types</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-10-26</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:table:service</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>sal-table</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-10-26</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:shutdown</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>shutdown</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-12-18</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:port:service</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>sal-port</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-11-07</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>netty-event-executor</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-11-12</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>sal-remote</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2014-01-14</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:model:topology:view</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-topology-view</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-10-30</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>threadgroup</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-11-07</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:TBD:params:xml:ns:yang:network-topology</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>network-topology</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-07-12</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:fixed</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>threadpool-impl-fixed</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-12-01</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-sal-binding-broker-impl</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-10-28</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-restconf</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>ietf-restconf</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-10-19</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:node:error:service</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>node-error</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2014-04-10</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:flow:errors</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>flow-errors</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-11-16</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:flow:service</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>sal-flow</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-08-19</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:ietf:params:xml:ns:yang:rpc-context</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>rpc-context</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-06-17</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:operational-dom-store
+        </ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-operational-dom-datastore</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2014-06-17</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:flow:types:queue</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-queue-types</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-09-25</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>ietf-netconf-monitoring</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2010-10-04</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:netconf-node-inventory</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>netconf-node-inventory</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2014-01-08</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-yang-types</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>ietf-yang-types</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-07-15</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:meter:statistics</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-meter-statistics</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-11-11</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:flow:inventory</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>flow-node-inventory</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-08-19</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>odl-sal-netconf-connector-cfg</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-10-28</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:scheduled</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>threadpool-impl-scheduled</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-12-01</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:TBD:params:xml:ns:yang:network-topology</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>network-topology</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-10-21</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>http://netconfcentral.org/ns/toaster</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>toaster</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2009-11-20</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:config:netconf</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>odl-netconf-cfg</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2014-04-08</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:meter:types</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-meter-types</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-09-18</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-sal-dom-broker-impl</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-10-28</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:flow:topology:discovery</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>flow-topology-discovery</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-08-19</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:yang:extension:yang-ext</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>yang-ext</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-07-09</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>threadpool-impl</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-04-05</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:flow:types:port</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-port-types</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-09-25</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-md-sal-binding</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-10-28</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:packet:service</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>packet-processing</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-07-09</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>threadpool-impl-flexible</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-12-01</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:queue:service</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>sal-queue</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-11-07</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-inet-types</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>ietf-inet-types</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2010-09-24</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:rest:connector</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-rest-connector</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2014-07-24</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:flow:transaction</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>flow-capable-transaction</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-11-03</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:flow:statistics</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-flow-statistics</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-08-19</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:protocol:framework</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>protocol-framework</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2014-03-13</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:model:match:types</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-match-types</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-10-26</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-yang-types</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>ietf-yang-types</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2010-09-24</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:group:service</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>sal-group</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-09-18</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:inmemory-datastore-provider</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-inmemory-datastore-provider</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2014-06-17</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:netty:timer</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>netty-timer</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-11-19</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:group:statistics</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-group-statistics</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-11-11</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:config</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>config</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-04-05</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>odl-netconfig-client-cfg</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2014-04-08</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:l2:types</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-l2-types</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-08-27</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:action:types</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-action-types</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-11-12</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-md-sal-dom</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-10-28</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:common</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-md-sal-common</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-10-28</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:group:types</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-group-types</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-10-18</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring-extension</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>ietf-netconf-monitoring-extension</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-12-10</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:inventory</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-inventory</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-08-19</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:netty</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>netty</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-11-19</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:model:topology:general</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-topology</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-10-30</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:port:statistics</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-port-statistics</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version></ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:queue:statistics</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-queue-statistics</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-12-16</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>kitchen-service-impl</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2014-01-31</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:flow:types</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-flow-types</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-10-26</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:shutdown:impl</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>shutdown-impl</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-12-18</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:model:topology:inventory</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-topology-inventory</ncm:identifier>
+        <ncm:format>yang</ncm:format>
+        <ncm:version>2013-10-30</ncm:version>
+    </ncm:schema>
+</ncm:schemas>
\ No newline at end of file