From 604341108d66bb0c9f554a896fcebf00ee5fca10 Mon Sep 17 00:00:00 2001 From: Tony Tkacik Date: Mon, 6 Jan 2014 20:44:26 +0100 Subject: [PATCH] Support for mount points in Restconf Added support for mount points in Restconf paths, which allows for deeper queries inside remote nodes such as Netconf. Change-Id: I348e494bae138f7d46ca70ab051f36b5b021641d Signed-off-by: Tony Tkacik --- .../sal/core/api/mount/MountInstance.java | 3 + .../api/mount/MountProvisionInstance.java | 4 + .../sal/dom/broker/MountPointImpl.java | 11 ++ .../sal/rest/impl/RestconfProvider.java | 2 + .../controller/sal/rest/impl/XmlMapper.java | 132 +----------------- .../sal/restconf/impl/ControllerContext.xtend | 100 ++++++++----- .../impl/test/ControllerContextTest.java | 58 +++++++- .../impl/test/ReadConfAndOperDataTest.java | 1 + 8 files changed, 136 insertions(+), 175 deletions(-) diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountInstance.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountInstance.java index 1596165601..910c7cb623 100644 --- a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountInstance.java +++ b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountInstance.java @@ -16,8 +16,11 @@ import org.opendaylight.controller.sal.core.api.notify.NotificationService; 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.model.api.SchemaContext; public interface MountInstance extends NotificationService, DataBrokerService { Future> rpc(QName type, CompositeNode input); + + SchemaContext getSchemaContext(); } diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionInstance.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionInstance.java index 92542bc345..e5fc4b7aa4 100644 --- a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionInstance.java +++ b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionInstance.java @@ -3,6 +3,8 @@ package org.opendaylight.controller.sal.core.api.mount; import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry; import org.opendaylight.controller.sal.core.api.data.DataProviderService; import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService; +import com.google.common.base.Optional; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; public interface MountProvisionInstance extends // MountInstance,// @@ -10,4 +12,6 @@ public interface MountProvisionInstance extends // RpcProvisionRegistry,// DataProviderService { + void setSchemaContext(SchemaContext optional); + } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointImpl.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointImpl.java index 7509a38a14..ab5b145064 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointImpl.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointImpl.java @@ -31,6 +31,7 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.InstanceIdentifierBuilder; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; public class MountPointImpl implements MountProvisionInstance { @@ -42,6 +43,8 @@ public class MountPointImpl implements MountProvisionInstance { private final InstanceIdentifier mountPath; + private SchemaContext schemaContext; + public MountPointImpl(InstanceIdentifier path) { this.mountPath = path; rpcs = new RpcRouterImpl(""); @@ -163,6 +166,14 @@ public class MountPointImpl implements MountProvisionInstance { // NOOP } + public SchemaContext getSchemaContext() { + return schemaContext; + } + + public void setSchemaContext(SchemaContext schemaContext) { + this.schemaContext = schemaContext; + } + class ReadWrapper implements DataReader { diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java index 242f18d240..1bceee88cb 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java @@ -9,6 +9,7 @@ import org.opendaylight.controller.sal.core.api.Provider; import org.opendaylight.controller.sal.core.api.data.DataBrokerService; import org.opendaylight.controller.sal.core.api.model.SchemaService; import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener; +import org.opendaylight.controller.sal.core.api.mount.MountService; import org.opendaylight.controller.sal.restconf.impl.BrokerFacade; import org.opendaylight.controller.sal.restconf.impl.ControllerContext; import org.opendaylight.yangtools.concepts.ListenerRegistration; @@ -37,6 +38,7 @@ public class RestconfProvider implements BundleActivator, Provider, ServiceTrack SchemaService schemaService = session.getService(SchemaService.class); listenerRegistration = schemaService.registerSchemaServiceListener(ControllerContext.getInstance()); ControllerContext.getInstance().setSchemas(schemaService.getGlobalContext()); + ControllerContext.getInstance().setMountService(session.getService(MountService.class)); } @Override diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java index a3d658e7bf..0e9bad046b 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java @@ -1,142 +1,14 @@ package org.opendaylight.controller.sal.rest.impl; -import java.util.Set; - import javax.activation.UnsupportedDataTypeException; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO; -import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.IdentityValue; -import org.opendaylight.controller.sal.restconf.impl.RestCodec; -import org.opendaylight.yangtools.yang.common.QName; 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.model.api.ChoiceCaseNode; -import org.opendaylight.yangtools.yang.model.api.ChoiceNode; -import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; -import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; -import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; -import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; -import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; -import org.opendaylight.yangtools.yang.model.api.TypeDefinition; -import org.opendaylight.yangtools.yang.model.api.YangNode; -import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.w3c.dom.Document; -import org.w3c.dom.Element; -import com.google.common.base.Preconditions; public class XmlMapper { - - private final Logger logger = LoggerFactory.getLogger(XmlMapper.class); - public Document write(CompositeNode data, DataNodeContainer schema) throws UnsupportedDataTypeException { - Preconditions.checkNotNull(data); - Preconditions.checkNotNull(schema); - - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - Document doc = null; - try { - DocumentBuilder bob = dbf.newDocumentBuilder(); - doc = bob.newDocument(); - } catch (ParserConfigurationException e) { - return null; - } - - if (schema instanceof ContainerSchemaNode || schema instanceof ListSchemaNode) { - doc.appendChild(translateToXmlAndReturnRootElement(doc, data, schema)); - return doc; - } else { - throw new UnsupportedDataTypeException( - "Schema can be ContainerSchemaNode or ListSchemaNode. Other types are not supported yet."); - } - } - - private Element translateToXmlAndReturnRootElement(Document doc, Node data, YangNode schema) - throws UnsupportedDataTypeException { - QName dataType = data.getNodeType(); - Element itemEl = doc.createElementNS(dataType.getNamespace().toString(), dataType.getLocalName()); - if (data instanceof SimpleNode) { - if (schema instanceof LeafListSchemaNode) { - writeValueOfNodeByType(itemEl, (SimpleNode) data, ((LeafListSchemaNode) schema).getType(), (DataSchemaNode) schema); - } else if (schema instanceof LeafSchemaNode) { - writeValueOfNodeByType(itemEl, (SimpleNode) data, ((LeafSchemaNode) schema).getType(), (DataSchemaNode) schema); - } else { - Object value = data.getValue(); - if (value != null) { - itemEl.setTextContent(String.valueOf(value)); - } - } - } else { // CompositeNode - for (Node child : ((CompositeNode) data).getChildren()) { - DataSchemaNode childSchema = null; - if(schema != null){ - childSchema = findFirstSchemaForNode(child, ((DataNodeContainer) schema).getChildNodes()); - if (logger.isDebugEnabled()) { - if (childSchema == null) { - logger.debug("Probably the data node \"" + ((child == null) ? "" : child.getNodeType().getLocalName()) - + "\" is not conform to schema"); - } - } - } - itemEl.appendChild(translateToXmlAndReturnRootElement(doc, child, childSchema)); - } - } - return itemEl; + return XmlDocumentUtils.toDocument(data, schema, XmlDocumentUtils.defaultValueCodecProvider()); } - - private void writeValueOfNodeByType(Element element, SimpleNode node, TypeDefinition type, DataSchemaNode schema) { - - TypeDefinition baseType = RestUtil.resolveBaseTypeFrom(type); - - if (baseType instanceof IdentityrefTypeDefinition) { - if (node.getValue() instanceof QName) { - IdentityValuesDTO valueDTO = (IdentityValuesDTO) RestCodec.from(type).serialize(node.getValue()); - IdentityValue value = valueDTO.getValuesWithNamespaces().get(0); - String prefix = "x"; - if (value.getPrefix() != null && !value.getPrefix().isEmpty()) { - prefix = value.getPrefix(); - } - element.setAttribute("xmlns:" + prefix, value.getNamespace()); - element.setTextContent(prefix + ":" + value.getValue()); - } else { - logger.debug("Value of " + baseType.getQName().getNamespace() + ":" - + baseType.getQName().getLocalName() + " is not instance of " + QName.class + " but is " + node.getValue().getClass()); - element.setTextContent(String.valueOf(node.getValue())); - } - } else { - if (node.getValue() != null) { - String value = String.valueOf(RestCodec.from(baseType).serialize(node.getValue())); - if (value.equals("null")) { - value = String.valueOf(node.getValue()); - } - element.setTextContent(value); - } - } - } - - private DataSchemaNode findFirstSchemaForNode(Node node, Set dataSchemaNode) { - if (dataSchemaNode != null && node != null) { - for (DataSchemaNode dsn : dataSchemaNode) { - if (node.getNodeType().getLocalName().equals(dsn.getQName().getLocalName())) { - return dsn; - } else if (dsn instanceof ChoiceNode) { - for (ChoiceCaseNode choiceCase : ((ChoiceNode) dsn).getCases()) { - DataSchemaNode foundDsn = findFirstSchemaForNode(node, choiceCase.getChildNodes()); - if (foundDsn != null) { - return foundDsn; - } - } - } - } - } - return null; - } - } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend index eec2d452a1..1a60e14589 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend @@ -34,13 +34,19 @@ import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition import org.slf4j.LoggerFactory import static com.google.common.base.Preconditions.* +import org.opendaylight.controller.sal.core.api.mount.MountService +import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode class ControllerContext implements SchemaServiceListener { val static LOG = LoggerFactory.getLogger(ControllerContext) val static ControllerContext INSTANCE = new ControllerContext val static NULL_VALUE = "null" - var SchemaContext schemas; + @Property + var SchemaContext globalSchema; + + @Property + var MountService mountService; private val BiMap uriToModuleName = HashBiMap.create(); private val Map moduleNameToUri = uriToModuleName.inverse(); @@ -57,7 +63,7 @@ class ControllerContext implements SchemaServiceListener { } private def void checkPreconditions() { - if (schemas === null) { + if (globalSchema === null) { throw new ResponseException(Response.Status.SERVICE_UNAVAILABLE, RestconfProvider::NOT_INITALIZED_MSG) } } @@ -75,29 +81,24 @@ class ControllerContext implements SchemaServiceListener { if (pathArgs.head.empty) { pathArgs.remove(0) } - val schemaNode = ret.collectPathArguments(pathArgs, restconfInstance.findModule); + val schemaNode = ret.collectPathArguments(pathArgs, globalSchema.findModule(pathArgs.head)); if (schemaNode === null) { return null } return new InstanceIdWithSchemaNode(ret.toInstance, schemaNode) } - private def findModule(String restconfInstance) { - checkPreconditions - checkNotNull(restconfInstance); - val pathArgs = restconfInstance.split("/"); - if (pathArgs.empty) { - return null; - } - val modulWithFirstYangStatement = pathArgs.filter[s|s.contains(":")].head - val startModule = modulWithFirstYangStatement.toModuleName(); - return getLatestModule(startModule) + private static def findModule(SchemaContext context,String argument) { + //checkPreconditions + checkNotNull(argument); + val startModule = argument.toModuleName(); + return context.getLatestModule(startModule) } - def getLatestModule(String moduleName) { - checkPreconditions + static def getLatestModule(SchemaContext schema,String moduleName) { + checkArgument(schema != null); checkArgument(moduleName !== null && !moduleName.empty) - val modules = schemas.modules.filter[m|m.name == moduleName] + val modules = schema.modules.filter[m|m.name == moduleName] var latestModule = modules.head for (module : modules) { if (module.revision.after(latestModule.revision)) { @@ -112,7 +113,7 @@ class ControllerContext implements SchemaServiceListener { val elements = path.path; val ret = new StringBuilder(); val startQName = elements.get(0).nodeType; - val initialModule = schemas.findModuleByNamespaceAndRevision(startQName.namespace, startQName.revision) + val initialModule = globalSchema.findModuleByNamespaceAndRevision(startQName.namespace, startQName.revision) var node = initialModule as DataSchemaNode; for (element : elements) { node = node.childByQName(element.nodeType); @@ -139,7 +140,7 @@ class ControllerContext implements SchemaServiceListener { checkPreconditions var module = uriToModuleName.get(namespace) if (module === null) { - val moduleSchemas = schemas.findModuleByNamespace(namespace); + val moduleSchemas = globalSchema.findModuleByNamespace(namespace); if(moduleSchemas === null) return null var latestModule = moduleSchemas.head for (m : moduleSchemas) { @@ -157,7 +158,7 @@ class ControllerContext implements SchemaServiceListener { def findNamespaceByModule(String module) { var namespace = moduleNameToUri.get(module) if (namespace === null) { - val moduleSchemas = schemas.modules.filter[it|it.name.equals(module)] + val moduleSchemas = globalSchema.modules.filter[it|it.name.equals(module)] var latestModule = moduleSchemas.head for (m : moduleSchemas) { if (m.revision.after(latestModule.revision)) { @@ -175,7 +176,7 @@ class ControllerContext implements SchemaServiceListener { checkPreconditions var module = uriToModuleName.get(qname.namespace) if (module === null) { - val moduleSchema = schemas.findModuleByNamespaceAndRevision(qname.namespace, qname.revision); + val moduleSchema = globalSchema.findModuleByNamespaceAndRevision(qname.namespace, qname.revision); if(moduleSchema === null) throw new IllegalArgumentException() uriToModuleName.put(qname.namespace, moduleSchema.name) module = moduleSchema.name; @@ -244,25 +245,22 @@ class ControllerContext implements SchemaServiceListener { } val nodeRef = strings.head; - val nodeName = nodeRef.toNodeName(); - val targetNode = parentNode.getDataChildByName(nodeName); - if (targetNode === null) { - val children = parentNode.childNodes - for (child : children) { - if (child instanceof ChoiceNode) { - val choice = child as ChoiceNode - for (caze : choice.cases) { - val result = builder.collectPathArguments(strings, caze as DataNodeContainer); - if (result !== null) - return result - } - } - } + val nodeName = nodeRef.toNodeName; + var targetNode = parentNode.findInstanceDataChild(nodeName); + if (targetNode instanceof ChoiceNode) { return null } - if (targetNode instanceof ChoiceNode) { + + if (targetNode === null) { + // Node is possibly in other mount point + val partialPath = builder.toInstance; + val mountPointSchema = mountService?.getMountPoint(partialPath)?.schemaContext; + if(mountPointSchema != null) { + return builder.collectPathArguments(strings, mountPointSchema.findModule(strings.head)); + } return null } + // Number of consumed elements var consumed = 1; @@ -302,6 +300,32 @@ class ControllerContext implements SchemaServiceListener { return targetNode } + + static def DataSchemaNode findInstanceDataChild(DataNodeContainer container, String name) { + // FIXME: Add namespace comparison + var potentialNode = container.getDataChildByName(name); + if(potentialNode.instantiatedDataSchema) { + return potentialNode; + } + val allCases = container.childNodes.filter(ChoiceNode).map[cases].flatten + for (caze : allCases) { + potentialNode = caze.findInstanceDataChild(name); + if(potentialNode != null) { + return potentialNode; + } + } + return null; + } + + static def boolean isInstantiatedDataSchema(DataSchemaNode node) { + switch node { + LeafSchemaNode: return true + LeafListSchemaNode: return true + ContainerSchemaNode: return true + ListSchemaNode: return true + default: return false + } + } private def void addKeyValue(HashMap map, DataSchemaNode node, String uriValue) { checkNotNull(uriValue); @@ -319,7 +343,7 @@ class ControllerContext implements SchemaServiceListener { map.put(node.QName, decoded); } - private def String toModuleName(String str) { + private static def String toModuleName(String str) { checkNotNull(str) if (str.contains(":")) { val args = str.split(":"); @@ -343,7 +367,7 @@ class ControllerContext implements SchemaServiceListener { private def QName toQName(String name) { val module = name.toModuleName; val node = name.toNodeName; - val namespace = FluentIterable.from(schemas.modules.sort[o1,o2 | o1.revision.compareTo(o2.revision)]) // + val namespace = FluentIterable.from(globalSchema.modules.sort[o1,o2 | o1.revision.compareTo(o2.revision)]) // .transform[QName.create(namespace,revision,it.name)].findFirst[module == localName] ; return QName.create(namespace,node); @@ -354,7 +378,7 @@ class ControllerContext implements SchemaServiceListener { } override onGlobalContextUpdated(SchemaContext context) { - this.schemas = context; + this.globalSchema = context; for (operation : context.operations) { val qname = operation.QName; qnameToRpc.put(qname, operation); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ControllerContextTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ControllerContextTest.java index 39c0d3b34f..08ec3f2b0c 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ControllerContextTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ControllerContextTest.java @@ -7,8 +7,15 @@ import java.util.Set; import org.junit.BeforeClass; import org.junit.Test; +import org.mockito.Mock; + +import static org.mockito.Mockito.*; + +import org.opendaylight.controller.sal.core.api.mount.MountInstance; +import org.opendaylight.controller.sal.core.api.mount.MountService; import org.opendaylight.controller.sal.restconf.impl.ControllerContext; import org.opendaylight.controller.sal.restconf.impl.InstanceIdWithSchemaNode; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; @@ -19,14 +26,16 @@ public class ControllerContextTest { @BeforeClass public static void init() throws FileNotFoundException { - Set allModules = TestUtils.loadModules(ControllerContextTest.class.getResource("/full-versions/yangs").getPath()); + Set allModules = TestUtils.loadModules(ControllerContextTest.class.getResource("/full-versions/yangs") + .getPath()); SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules); controllerContext.setSchemas(schemaContext); } @Test public void testToInstanceIdentifierList() throws FileNotFoundException { - InstanceIdWithSchemaNode instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:userWithoutClass/foo"); + InstanceIdWithSchemaNode instanceIdentifier = controllerContext + .toInstanceIdentifier("simple-nodes:userWithoutClass/foo"); assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "userWithoutClass"); instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:userWithoutClass/foo/full-name"); @@ -49,28 +58,63 @@ public class ControllerContextTest { } + @Test + public void testToInstanceIdentifierMountPoint() throws FileNotFoundException { + try { + String mountPointPath = "simple-nodes:user/foo/boo"; + String nestedPath = "simple-nodes:user/foo/boo/simple-nodes:users"; + InstanceIdWithSchemaNode mountInstanceIdentifier = controllerContext.toInstanceIdentifier(mountPointPath); + assertEquals("user", mountInstanceIdentifier.getSchemaNode().getQName().getLocalName()); + + MountInstance mountInstance = mock(MountInstance.class); + MountService mountService = mock(MountService.class); + + controllerContext.setMountService(mountService); + // when(mountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(null); + + when(mountService.getMountPoint(eq(mountInstanceIdentifier.getInstanceIdentifier()))).thenReturn( + mountInstance); + + when(mountInstance.getSchemaContext()).thenReturn(controllerContext.getGlobalSchema()); + + InstanceIdWithSchemaNode mountedInstanceIdentifier = controllerContext.toInstanceIdentifier(nestedPath); + assertEquals("users", mountedInstanceIdentifier.getSchemaNode().getQName().getLocalName()); + + mountedInstanceIdentifier = controllerContext.toInstanceIdentifier(mountPointPath + "/" + mountPointPath); + assertEquals("user", mountedInstanceIdentifier.getSchemaNode().getQName().getLocalName()); + + mountedInstanceIdentifier = controllerContext + .toInstanceIdentifier("simple-nodes:user/foo/var/simple-nodes:users"); + assertNull(mountedInstanceIdentifier); + + } finally { + controllerContext.setMountService(null); + } + + } + @Test public void testToInstanceIdentifierContainer() throws FileNotFoundException { InstanceIdWithSchemaNode instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:users"); assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "users"); assertTrue(instanceIdentifier.getSchemaNode() instanceof ContainerSchemaNode); - assertEquals(2, ((ContainerSchemaNode)instanceIdentifier.getSchemaNode()).getChildNodes().size()); + assertEquals(2, ((ContainerSchemaNode) instanceIdentifier.getSchemaNode()).getChildNodes().size()); } @Test public void testToInstanceIdentifierChoice() throws FileNotFoundException { InstanceIdWithSchemaNode instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/beer"); assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "beer"); - + instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/snack"); assertNull(instanceIdentifier); - + instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/sports-arena"); assertNull(instanceIdentifier); - + instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/snack/sports-arena"); assertNull(instanceIdentifier); - + } } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ReadConfAndOperDataTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ReadConfAndOperDataTest.java index cac77eb368..0bb03cb0ad 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ReadConfAndOperDataTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ReadConfAndOperDataTest.java @@ -86,6 +86,7 @@ public class ReadConfAndOperDataTest extends JerseyTest { public void testReadOperationalData() throws UnsupportedEncodingException, FileNotFoundException { String uri = createUri("/operational/", "ietf-interfaces:interfaces/interface/eth0"); + CompositeNode loadedCompositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder("/parts/ietf-interfaces_interfaces.xml"); when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode); -- 2.36.6