From 5957a742796f6a1426e406a54002d9decc7a7188 Mon Sep 17 00:00:00 2001 From: Maros Marsalek Date: Tue, 29 Jul 2014 17:06:44 +0200 Subject: [PATCH] BUG-997 Consult QNames of yang modules with ietf-netconf-monitoring/netconf-state/schemas Change-Id: Ie0fcb6d9ba44207cb14d31d51c1f3068983d514e Signed-off-by: Maros Marsalek --- .../sal/connect/netconf/NetconfDevice.java | 42 +- .../connect/netconf/NetconfStateSchemas.java | 213 ++++++++ .../listener/NetconfDeviceCommunicator.java | 2 +- .../sal/tx/NetconfDeviceReadOnlyTx.java | 33 +- .../mapping/NetconfMessageTransformer.java | 2 +- .../util/NetconfMessageTransformUtil.java | 37 +- .../connect/netconf/NetconfDeviceTest.java | 22 +- .../netconf/NetconfStateSchemasTest.java | 29 + .../netconf-state.schemas.payload.xml | 514 ++++++++++++++++++ 9 files changed, 840 insertions(+), 54 deletions(-) create mode 100644 opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemas.java create mode 100644 opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemasTest.java create mode 100644 opendaylight/md-sal/sal-netconf-connector/src/test/resources/netconf-state.schemas.payload.xml diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java index 07d3c08774..350132cf99 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java @@ -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 messageTransformer; private final SchemaContextProviderFactory schemaContextProviderFactory; private final SchemaSourceProviderFactory sourceProviderFactory; + private final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver; private final NotificationHandler notificationHandler; public static NetconfDevice createNetconfDevice(final RemoteDeviceId id, final AbstractCachingSchemaSourceProvider schemaSourceProvider, final ExecutorService executor, final RemoteDeviceHandler salFacade) { + return createNetconfDevice(id, schemaSourceProvider, executor, salFacade, new NetconfStateSchemas.NetconfStateSchemasResolverImpl()); + } + + @VisibleForTesting + protected static NetconfDevice createNetconfDevice(final RemoteDeviceId id, + final AbstractCachingSchemaSourceProvider schemaSourceProvider, + final ExecutorService executor, final RemoteDeviceHandler salFacade, + final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver) { return new NetconfDevice(id, salFacade, executor, new NetconfMessageTransformer(), new NetconfDeviceSchemaProviderFactory(id), new SchemaSourceProviderFactory() { @@ -67,18 +78,20 @@ public final class NetconfDevice implements RemoteDevice salFacade, - final ExecutorService processingExecutor, final MessageTransformer messageTransformer, - final SchemaContextProviderFactory schemaContextProviderFactory, - final SchemaSourceProviderFactory sourceProviderFactory) { + final ExecutorService processingExecutor, final MessageTransformer messageTransformer, + final SchemaContextProviderFactory schemaContextProviderFactory, + final SchemaSourceProviderFactory 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 delegate = sourceProviderFactory.createSourceProvider(deviceRpc); final SchemaContextProvider schemaContextProvider = setUpSchemaContext(delegate, remoteSessionCapabilities); updateMessageTransformer(schemaContextProvider); @@ -204,6 +222,6 @@ public final class NetconfDevice implements RemoteDeviceemptySet()); + + 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.>newArrayList(filter)); + } + + private final Set availableYangSchemas; + + public NetconfStateSchemas(final Set availableYangSchemas) { + this.availableYangSchemas = availableYangSchemas; + } + + public Set getAvailableYangSchemas() { + return availableYangSchemas; + } + + public Set getAvailableYangSchemasQNames() { + return Sets.newHashSet(Collections2.transform(getAvailableYangSchemas(), new Function() { + @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 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 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 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 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 getAllChildNodeValues(final CompositeNode schemaNode, final QName childNodeQName) { + final Set extractedValues = Sets.newHashSet(); + for (final SimpleNode childNode : schemaNode.getSimpleNodesByName(childNodeQName)) { + extractedValues.add(getValueOfSimpleNode(childNodeQName, childNode).get()); + } + return extractedValues; + } + + private static Optional getSingleChildNodeValue(final CompositeNode schemaNode, final QName childNode) { + final SimpleNode node = schemaNode.getFirstSimpleByName(childNode); + return getValueOfSimpleNode(childNode, node); + } + + private static Optional 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.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(); + } + } +} diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCommunicator.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCommunicator.java index 3871cdfa4f..2f24adcdbe 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCommunicator.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCommunicator.java @@ -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 ); diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceReadOnlyTx.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceReadOnlyTx.java index 533df9cce7..04a99511a1 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceReadOnlyTx.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceReadOnlyTx.java @@ -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.>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.>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 diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java index 47ef9039d1..5e61dfb028 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java @@ -96,7 +96,7 @@ public class NetconfMessageTransformer implements MessageTransformer 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; + } } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java b/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java index 46ea4ff73c..fa488dadd3 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java @@ -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 facade = getFacade(); final RemoteDeviceCommunicator 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.emptyList()), listener); Mockito.verify(facade, Mockito.timeout(5000)).onDeviceDisconnected(); @@ -89,7 +95,7 @@ public class NetconfDeviceTest { final RemoteDeviceCommunicator listener = getListener(); final MessageTransformer 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 sourceProviderFactory = getSourceProviderFactory(); final MessageTransformer 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 + "&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 index 0000000000..16a915e730 --- /dev/null +++ b/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemasTest.java @@ -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 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 index 0000000000..649ecb76a4 --- /dev/null +++ b/opendaylight/md-sal/sal-netconf-connector/src/test/resources/netconf-state.schemas.payload.xml @@ -0,0 +1,514 @@ + + + urn:opendaylight:params:xml:ns:yang:controller:threadpool + NETCONF + threadpool + yang + 2013-04-09 + + + urn:opendaylight:params:xml:ns:yang:controller:logback:config + NETCONF + config-logging + yang + 2013-07-16 + + + urn:opendaylight:model:statistics:types + NETCONF + opendaylight-statistics-types + yang + 2013-09-25 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:config-dom-store + NETCONF + opendaylight-config-dom-datastore + yang + 2014-06-17 + + + urn:opendaylight:flow:table:statistics + NETCONF + opendaylight-flow-table-statistics + yang + 2013-12-15 + + + urn:opendaylight:meter:service + NETCONF + sal-meter + yang + 2013-09-18 + + + urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl + NETCONF + toaster-provider-impl + yang + 2014-01-31 + + + urn:opendaylight:table:types + NETCONF + opendaylight-table-types + yang + 2013-10-26 + + + urn:opendaylight:table:service + NETCONF + sal-table + yang + 2013-10-26 + + + urn:opendaylight:params:xml:ns:yang:controller:shutdown + NETCONF + shutdown + yang + 2013-12-18 + + + urn:opendaylight:port:service + NETCONF + sal-port + yang + 2013-11-07 + + + urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor + NETCONF + netty-event-executor + yang + 2013-11-12 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote + NETCONF + sal-remote + yang + 2014-01-14 + + + urn:opendaylight:model:topology:view + NETCONF + opendaylight-topology-view + yang + 2013-10-30 + + + urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup + NETCONF + threadgroup + yang + 2013-11-07 + + + urn:TBD:params:xml:ns:yang:network-topology + NETCONF + network-topology + yang + 2013-07-12 + + + urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:fixed + NETCONF + threadpool-impl-fixed + yang + 2013-12-01 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl + NETCONF + opendaylight-sal-binding-broker-impl + yang + 2013-10-28 + + + urn:ietf:params:xml:ns:yang:ietf-restconf + NETCONF + ietf-restconf + yang + 2013-10-19 + + + urn:opendaylight:node:error:service + NETCONF + node-error + yang + 2014-04-10 + + + urn:opendaylight:flow:errors + NETCONF + flow-errors + yang + 2013-11-16 + + + urn:opendaylight:flow:service + NETCONF + sal-flow + yang + 2013-08-19 + + + urn:ietf:params:xml:ns:yang:rpc-context + NETCONF + rpc-context + yang + 2013-06-17 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:operational-dom-store + + NETCONF + opendaylight-operational-dom-datastore + yang + 2014-06-17 + + + urn:opendaylight:flow:types:queue + NETCONF + opendaylight-queue-types + yang + 2013-09-25 + + + urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring + NETCONF + ietf-netconf-monitoring + yang + 2010-10-04 + + + urn:opendaylight:netconf-node-inventory + NETCONF + netconf-node-inventory + yang + 2014-01-08 + + + urn:ietf:params:xml:ns:yang:ietf-yang-types + NETCONF + ietf-yang-types + yang + 2013-07-15 + + + urn:opendaylight:meter:statistics + NETCONF + opendaylight-meter-statistics + yang + 2013-11-11 + + + urn:opendaylight:flow:inventory + NETCONF + flow-node-inventory + yang + 2013-08-19 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf + NETCONF + odl-sal-netconf-connector-cfg + yang + 2013-10-28 + + + urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:scheduled + NETCONF + threadpool-impl-scheduled + yang + 2013-12-01 + + + urn:TBD:params:xml:ns:yang:network-topology + NETCONF + network-topology + yang + 2013-10-21 + + + http://netconfcentral.org/ns/toaster + NETCONF + toaster + yang + 2009-11-20 + + + urn:opendaylight:params:xml:ns:yang:controller:config:netconf + NETCONF + odl-netconf-cfg + yang + 2014-04-08 + + + urn:opendaylight:meter:types + NETCONF + opendaylight-meter-types + yang + 2013-09-18 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl + NETCONF + opendaylight-sal-dom-broker-impl + yang + 2013-10-28 + + + urn:opendaylight:flow:topology:discovery + NETCONF + flow-topology-discovery + yang + 2013-08-19 + + + urn:opendaylight:yang:extension:yang-ext + NETCONF + yang-ext + yang + 2013-07-09 + + + urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl + NETCONF + threadpool-impl + yang + 2013-04-05 + + + urn:opendaylight:flow:types:port + NETCONF + opendaylight-port-types + yang + 2013-09-25 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding + NETCONF + opendaylight-md-sal-binding + yang + 2013-10-28 + + + urn:opendaylight:packet:service + NETCONF + packet-processing + yang + 2013-07-09 + + + urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible + NETCONF + threadpool-impl-flexible + yang + 2013-12-01 + + + urn:opendaylight:queue:service + NETCONF + sal-queue + yang + 2013-11-07 + + + urn:ietf:params:xml:ns:yang:ietf-inet-types + NETCONF + ietf-inet-types + yang + 2010-09-24 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:rest:connector + NETCONF + opendaylight-rest-connector + yang + 2014-07-24 + + + urn:opendaylight:flow:transaction + NETCONF + flow-capable-transaction + yang + 2013-11-03 + + + urn:opendaylight:flow:statistics + NETCONF + opendaylight-flow-statistics + yang + 2013-08-19 + + + urn:opendaylight:params:xml:ns:yang:controller:protocol:framework + NETCONF + protocol-framework + yang + 2014-03-13 + + + urn:opendaylight:model:match:types + NETCONF + opendaylight-match-types + yang + 2013-10-26 + + + urn:ietf:params:xml:ns:yang:ietf-yang-types + NETCONF + ietf-yang-types + yang + 2010-09-24 + + + urn:opendaylight:group:service + NETCONF + sal-group + yang + 2013-09-18 + + + urn:opendaylight:params:xml:ns:yang:controller:inmemory-datastore-provider + NETCONF + opendaylight-inmemory-datastore-provider + yang + 2014-06-17 + + + urn:opendaylight:params:xml:ns:yang:controller:netty:timer + NETCONF + netty-timer + yang + 2013-11-19 + + + urn:opendaylight:group:statistics + NETCONF + opendaylight-group-statistics + yang + 2013-11-11 + + + urn:opendaylight:params:xml:ns:yang:controller:config + NETCONF + config + yang + 2013-04-05 + + + urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher + NETCONF + odl-netconfig-client-cfg + yang + 2014-04-08 + + + urn:opendaylight:l2:types + NETCONF + opendaylight-l2-types + yang + 2013-08-27 + + + urn:opendaylight:action:types + NETCONF + opendaylight-action-types + yang + 2013-11-12 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom + NETCONF + opendaylight-md-sal-dom + yang + 2013-10-28 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:common + NETCONF + opendaylight-md-sal-common + yang + 2013-10-28 + + + urn:opendaylight:group:types + NETCONF + opendaylight-group-types + yang + 2013-10-18 + + + urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring-extension + NETCONF + ietf-netconf-monitoring-extension + yang + 2013-12-10 + + + urn:opendaylight:inventory + NETCONF + opendaylight-inventory + yang + 2013-08-19 + + + urn:opendaylight:params:xml:ns:yang:controller:netty + NETCONF + netty + yang + 2013-11-19 + + + urn:opendaylight:model:topology:general + NETCONF + opendaylight-topology + yang + 2013-10-30 + + + urn:opendaylight:port:statistics + NETCONF + opendaylight-port-statistics + yang + + + + urn:opendaylight:queue:statistics + NETCONF + opendaylight-queue-statistics + yang + 2013-12-16 + + + urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl + NETCONF + kitchen-service-impl + yang + 2014-01-31 + + + urn:opendaylight:flow:types + NETCONF + opendaylight-flow-types + yang + 2013-10-26 + + + urn:opendaylight:params:xml:ns:yang:controller:shutdown:impl + NETCONF + shutdown-impl + yang + 2013-12-18 + + + urn:opendaylight:model:topology:inventory + NETCONF + opendaylight-topology-inventory + yang + 2013-10-30 + + \ No newline at end of file -- 2.36.6