From 521d199e057a03929ad64925d7d37ba79deba167 Mon Sep 17 00:00:00 2001 From: msunal Date: Tue, 29 Oct 2013 17:11:49 +0100 Subject: [PATCH] Added case with Choice-case to instance identifier building - Choice-case is resolved when instance identifier is builded - added tests for creating instance identifier from uri Change-Id: Ic61820d0d73cae43db50e0d1434e20b51ea54aa8 Signed-off-by: Martin Sunal --- .../sal/restconf/impl/ControllerContext.xtend | 45 +++++++++--- .../impl/test/ControllerContextTest.java | 53 ++++++++++++-- .../restconf/impl/test/JsonMapperTest.java | 1 - .../restconf/impl/test/RestconfImplTest.java | 1 - .../full-versions/yangs/simple-nodes.yang | 70 +++++++++++++++++++ 5 files changed, 153 insertions(+), 17 deletions(-) create mode 100644 opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/yangs/simple-nodes.yang 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 419ca50ee9..2218023caf 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 @@ -24,9 +24,10 @@ import org.opendaylight.yangtools.yang.model.api.ListSchemaNode import org.opendaylight.yangtools.yang.model.api.SchemaContext import static com.google.common.base.Preconditions.* -import java.util.Date class ControllerContext { + + val static NULL_VALUE = "null" @Property SchemaContext schemas; @@ -40,11 +41,17 @@ class ControllerContext { if (pathArgs.empty) { return null; } + if (pathArgs.head.empty) { + pathArgs.remove(0) + } val schemaNode = ret.collectPathArguments(pathArgs, restconfInstance.findModule); + if (schemaNode == null) { + return null + } new InstanceIdWithSchemaNode(ret.toInstance, schemaNode) } - def findModule(String restconfInstance) { + private def findModule(String restconfInstance) { checkNotNull(restconfInstance); val pathArgs = restconfInstance.split("/"); if (pathArgs.empty) { @@ -95,7 +102,7 @@ class ControllerContext { throw new IllegalArgumentException("Conversion of generic path argument is not supported"); } - public def CharSequence toRestconfIdentifier(QName qname) { + def CharSequence toRestconfIdentifier(QName qname) { var module = uriToModuleName.get(qname.namespace) if (module == null) { val moduleSchema = schemas.findModuleByNamespaceAndRevision(qname.namespace, qname.revision); @@ -156,7 +163,7 @@ class ControllerContext { return URLEncoder.encode(object.toString) } - def DataSchemaNode collectPathArguments(InstanceIdentifierBuilder builder, List strings, + private def DataSchemaNode collectPathArguments(InstanceIdentifierBuilder builder, List strings, DataNodeContainer parentNode) { checkNotNull(strings) if (strings.empty) { @@ -164,10 +171,23 @@ class ControllerContext { } val nodeRef = strings.head; - //val moduleName = nodeRef.toModuleName(); 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 + } + } + } + return null + } + if (targetNode instanceof ChoiceNode) { return null } @@ -176,18 +196,25 @@ class ControllerContext { if (targetNode instanceof ListSchemaNode) { val listNode = targetNode as ListSchemaNode; val keysSize = listNode.keyDefinition.size + // every key has to be filled + if ((strings.length - consumed) < keysSize) { + return null; + } val uriKeyValues = strings.subList(consumed, consumed + keysSize); val keyValues = new HashMap(); var i = 0; for (key : listNode.keyDefinition) { val uriKeyValue = uriKeyValues.get(i); + // key value cannot be NULL + if (uriKeyValue.equals(NULL_VALUE)) { + return null + } keyValues.addKeyValue(listNode.getDataChildByName(key), uriKeyValue); i = i + 1; } consumed = consumed + i; builder.nodeWithKey(targetNode.QName, keyValues); } else { - // Only one instance of node is allowed builder.node(targetNode.QName); } @@ -200,7 +227,7 @@ class ControllerContext { return targetNode } - def void addKeyValue(HashMap map, DataSchemaNode node, String uriValue) { + private def void addKeyValue(HashMap map, DataSchemaNode node, String uriValue) { checkNotNull(uriValue); checkArgument(node instanceof LeafSchemaNode); val decoded = URLDecoder.decode(uriValue); @@ -208,7 +235,7 @@ class ControllerContext { } - def String toModuleName(String str) { + private def String toModuleName(String str) { checkNotNull(str) if (str.contains(":")) { val args = str.split(":"); @@ -219,7 +246,7 @@ class ControllerContext { } } - def String toNodeName(String str) { + private def String toNodeName(String str) { if (str.contains(":")) { val args = str.split(":"); checkArgument(args.size === 2); 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 9916278dfe..8460140101 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 @@ -1,6 +1,6 @@ package org.opendaylight.controller.sal.restconf.impl.test; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; import java.io.FileNotFoundException; import java.util.Set; @@ -9,7 +9,7 @@ import org.junit.BeforeClass; import org.junit.Test; import org.opendaylight.controller.sal.restconf.impl.ControllerContext; import org.opendaylight.controller.sal.restconf.impl.InstanceIdWithSchemaNode; -import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; @@ -20,16 +20,57 @@ public class ControllerContextTest { @BeforeClass public static void init() throws FileNotFoundException { Set allModules = TestUtils.loadModules(ControllerContextTest.class.getResource("/full-versions/yangs").getPath()); - assertEquals(4, allModules.size()); SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules); controllerContext.setSchemas(schemaContext); } @Test public void testToInstanceIdentifierList() throws FileNotFoundException { - InstanceIdWithSchemaNode instanceIdentifier = controllerContext.toInstanceIdentifier("ietf-interfaces:interfaces/interface/foo"); - DataSchemaNode schemaNode = instanceIdentifier.getSchemaNode(); - assertEquals(schemaNode.getQName().getLocalName(), "interface"); + InstanceIdWithSchemaNode instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:userWithoutClass/foo"); + assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "userWithoutClass"); + + instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:userWithoutClass/foo/full-name"); + assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "full-name"); + + instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:user/foo/boo"); + assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "user"); + + instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:user//boo"); + assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "user"); + + instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:users/user/foo"); + assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "user"); + + instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:user/null/boo"); + assertNull(instanceIdentifier); + + instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:user/foo"); + assertNull(instanceIdentifier); + + } + + @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()); + } + + @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/JsonMapperTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/JsonMapperTest.java index b1d7d2281c..18a5d7ad13 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/JsonMapperTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/JsonMapperTest.java @@ -22,7 +22,6 @@ public class JsonMapperTest { @BeforeClass public static void init() throws FileNotFoundException { Set allModules = TestUtils.loadModules(JsonMapperTest.class.getResource("/full-versions/yangs").getPath()); - assertEquals(4, allModules.size()); SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules); controllerContext.setSchemas(schemaContext); } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfImplTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfImplTest.java index 8263c467b0..292dfd8e28 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfImplTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfImplTest.java @@ -24,7 +24,6 @@ public class RestconfImplTest { @BeforeClass public static void init() throws FileNotFoundException { Set allModules = TestUtils.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs").getPath()); - assertEquals(4, allModules.size()); SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules); ControllerContext controllerContext = new ControllerContext(); controllerContext.setSchemas(schemaContext); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/yangs/simple-nodes.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/yangs/simple-nodes.yang new file mode 100644 index 0000000000..674b8b09be --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/yangs/simple-nodes.yang @@ -0,0 +1,70 @@ +module simple-nodes { + yang-version 1; + namespace "urn:opendaylight:simple-nodes"; + prefix "sn"; + + description + "test file containing yang data nodes"; + + revision "2013-07-30" { + description + "Initial revision."; + reference "will be defined"; + } + + container users { + leaf user { + type string; + } + + leaf group { + type string; + } + } + + list user { + key "name class"; + leaf name { + type string; + } + leaf full-name { + type string; + } + leaf class { + type string; + } + } + + list userWithoutClass { + key "name"; + leaf name { + type string; + } + leaf full-name { + type string; + } + } + + container food { + choice snack { + case sports-arena { + leaf pretzel { + type string; + } + leaf beer { + type string; + } + } + case late-night { + leaf chocolate { + type enumeration { + enum dark; + enum milk; + enum first-available; + } + } + } + } + } + +} -- 2.36.6