From: Jozef Gloncak Date: Wed, 23 Apr 2014 12:56:10 +0000 (+0200) Subject: BUG 652 leafref CCE & BUG 720 colons problem X-Git-Tag: autorelease-tag-v20140601202136_82eb3f9~169^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=874d0e74084fc55af280a97052570c8cccf60821 BUG 652 leafref CCE & BUG 720 colons problem BUG 652 leafref Class cast exception By default if input data were in format which was possible to parse as XPath if was done like this. It caused that for leafref which indexed to instance-identifier the value was parsed as XPath and not as string. BUG 720 colons problem in JSON If input string contained colon (:) then it was dealed as namespace:value and object of type IdentityValuesDTO was created (it is probable that data could be of type identityref). If data wasn't of type leafref then it was incorrectly processed as leafref. The RestCodec was updated to correctly translate data (cases when data contains ':' but aren't of type leafref) Change-Id: I0cba06bce1b1c69f6901cc90d2b30a3735e5f57e Signed-off-by: Jozef Gloncak --- diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonReader.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonReader.java index e19f9f5805..4d9958ee6b 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonReader.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonReader.java @@ -122,7 +122,7 @@ class JsonReader { // it could be identityref Built-In Type URI namespace = getNamespaceFor(value); if (namespace != null) { - return new IdentityValuesDTO(namespace.toString(), getLocalNameFor(value), null); + return new IdentityValuesDTO(namespace.toString(), getLocalNameFor(value), null,value); } // it is not "prefix:value" but just "value" return value; diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestUtil.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestUtil.java index 225eb7de6a..ba3e315e72 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestUtil.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestUtil.java @@ -42,7 +42,7 @@ public final class RestUtil { if (xPathParts.length < 2) { // must be at least "/pr:node" return null; } - IdentityValuesDTO identityValuesDTO = new IdentityValuesDTO(); + IdentityValuesDTO identityValuesDTO = new IdentityValuesDTO(value); for (int i = 1; i < xPathParts.length; i++) { String xPathPartTrimmed = xPathParts[i].trim(); diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlReader.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlReader.java index d807070dbd..a75f6b4a85 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlReader.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlReader.java @@ -205,7 +205,7 @@ public class XmlReader { if (namespaceAndValue.length == 2) { String namespace = startElement.getNamespaceContext().getNamespaceURI(namespaceAndValue[0]); if (namespace != null && !namespace.isEmpty()) { - return new IdentityValuesDTO(namespace, namespaceAndValue[1], namespaceAndValue[0]); + return new IdentityValuesDTO(namespace, namespaceAndValue[1], namespaceAndValue[0],value); } } // it is not "prefix:value" but just "value" diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/IdentityValuesDTO.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/IdentityValuesDTO.java index 4fb75141d5..14a558967d 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/IdentityValuesDTO.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/IdentityValuesDTO.java @@ -14,13 +14,19 @@ import java.util.List; public final class IdentityValuesDTO { private final List elementData = new ArrayList<>(); + private final String originValue; - public IdentityValuesDTO(String namespace, String value, String prefix) { + public IdentityValuesDTO(String namespace, String value, String prefix,String originValue) { elementData.add(new IdentityValue(namespace, value, prefix)); + this.originValue = originValue; + } + + public IdentityValuesDTO(String originValue) { + this.originValue = originValue; } public IdentityValuesDTO() { - + originValue = null; } public void add(String namespace, String value, String prefix) { @@ -40,6 +46,10 @@ public final class IdentityValuesDTO { public String toString() { return elementData.toString(); } + + public String getOriginValue() { + return originValue; + } public static final class IdentityValue { diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java index d6b530039e..42658d79f1 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java @@ -89,6 +89,9 @@ public class RestCodec { input == null ? "null" : input.getClass(), String.valueOf(input)); return null; } else if (type instanceof LeafrefTypeDefinition) { + if (input instanceof IdentityValuesDTO) { + return LEAFREF_DEFAULT_CODEC.deserialize(((IdentityValuesDTO)input).getOriginValue()); + } return LEAFREF_DEFAULT_CODEC.deserialize(input); } else if (type instanceof InstanceIdentifierTypeDefinition) { if (input instanceof IdentityValuesDTO) { @@ -102,6 +105,9 @@ public class RestCodec { TypeDefinitionAwareCodec> typeAwarecodec = TypeDefinitionAwareCodec .from(type); if (typeAwarecodec != null) { + if (input instanceof IdentityValuesDTO) { + return typeAwarecodec.deserialize(((IdentityValuesDTO)input).getOriginValue()); + } return typeAwarecodec.deserialize(String.valueOf(input)); } else { logger.debug("Codec for type \"" + type.getQName().getLocalName() @@ -162,7 +168,7 @@ public class RestCodec { @Override public IdentityValuesDTO serialize(QName data) { - return new IdentityValuesDTO(data.getNamespace().toString(), data.getLocalName(), data.getPrefix()); + return new IdentityValuesDTO(data.getNamespace().toString(), data.getLocalName(), data.getPrefix(),null); } @Override diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend index fa478ac72e..a0bd99c5d2 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend @@ -669,7 +669,7 @@ class RestconfImpl implements RestconfService { if (schema.typeDefinition instanceof IdentityrefTypeDefinition) { if (value instanceof String) { - inputValue = new IdentityValuesDTO(nodeBuilder.namespace.toString, value as String, null) + inputValue = new IdentityValuesDTO(nodeBuilder.namespace.toString, value as String, null,value as String); } // else value is already instance of IdentityValuesDTO } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlAndJsonToCnSnLeafRefTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlAndJsonToCnSnLeafRefTest.java new file mode 100644 index 0000000000..e5a737e6d5 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlAndJsonToCnSnLeafRefTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.restconf.impl.test; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.net.URISyntaxException; + +import javax.ws.rs.WebApplicationException; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider; +import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.Node; +import org.opendaylight.yangtools.yang.data.api.SimpleNode; + +public class XmlAndJsonToCnSnLeafRefTest extends YangAndXmlAndDataSchemaLoader { + + @BeforeClass + public static void initialize() { + dataLoad("/leafref/yang", 2, "leafref-module", "cont"); + } + + @Test + public void loadXmlToCnSn() throws WebApplicationException, IOException, URISyntaxException { + CompositeNode cnSn = TestUtils.readInputToCnSn("/leafref/xml/xmldata.xml", XmlToCompositeNodeProvider.INSTANCE); + TestUtils.normalizeCompositeNode(cnSn, modules, schemaNodePath); + verifyContPredicate(cnSn, "/ns:cont/ns:lf1", "/cont/lf1", "/ns:cont/ns:lf1", "../lf1"); + } + + @Test + public void loadJsonToCnSn() throws WebApplicationException, IOException, URISyntaxException { + CompositeNode cnSn = TestUtils.readInputToCnSn("/leafref/json/jsondata.json", + JsonToCompositeNodeProvider.INSTANCE); + TestUtils.normalizeCompositeNode(cnSn, modules, schemaNodePath); + verifyContPredicate(cnSn, "/leafref-module:cont/leafref-module:lf1", "/leafref-module:cont/leafref-module:lf1", + "/referenced-module:cont/referenced-module:lf1", "/leafref-module:cont/leafref-module:lf1"); + } + + private void verifyContPredicate(CompositeNode cnSn, String... values) throws URISyntaxException { + Object lf2Value = null; + Object lf3Value = null; + Object lf4Value = null; + Object lf5Value = null; + + for (Node node : cnSn.getValue()) { + if (node.getNodeType().getLocalName().equals("lf2")) { + lf2Value = ((SimpleNode) node).getValue(); + } else if (node.getNodeType().getLocalName().equals("lf3")) { + lf3Value = ((SimpleNode) node).getValue(); + } else if (node.getNodeType().getLocalName().equals("lf4")) { + lf4Value = ((SimpleNode) node).getValue(); + } else if (node.getNodeType().getLocalName().equals("lf5")) { + lf5Value = ((SimpleNode) node).getValue(); + } + } + assertEquals(values[0], lf2Value); + assertEquals(values[1], lf3Value); + assertEquals(values[2], lf4Value); + assertEquals(values[3], lf5Value); + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/json/jsondata.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/json/jsondata.json new file mode 100644 index 0000000000..cbe455b33b --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/json/jsondata.json @@ -0,0 +1,8 @@ +{ + "leafref-module:cont" : { + "lf4" : "/referenced-module:cont/referenced-module:lf1", + "lf2" : "/leafref-module:cont/leafref-module:lf1", + "lf3" : "/leafref-module:cont/leafref-module:lf1", + "lf5" : "/leafref-module:cont/leafref-module:lf1" + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/xml/xmldata.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/xml/xmldata.xml new file mode 100644 index 0000000000..01bf092d27 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/xml/xmldata.xml @@ -0,0 +1,6 @@ + + /ns:cont/ns:lf1 + /ns:cont/ns:lf1 + /cont/lf1 + ../lf1 + diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/yang/leafref-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/yang/leafref-module.yang new file mode 100644 index 0000000000..00df290691 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/yang/leafref-module.yang @@ -0,0 +1,44 @@ +module leafref-module { + namespace "leafref:module"; + + + prefix "lfrfmodule"; + + import referenced-module { prefix refmod; revision-date 2014-04-17;} + + + revision 2014-04-17 { + } + + + container cont { + leaf lf1 { + type instance-identifier; + } + + leaf lf2 { + type leafref { + path "../lf1"; + } + } + + leaf lf3 { + type leafref { + path "/refmod:cont/refmod:lf1"; + } + } + + leaf lf4 { + type leafref { + path "/cont/lf1"; + } + } + + leaf lf5 { + type leafref { + path "../lf1"; + } + } + + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/yang/referenced-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/yang/referenced-module.yang new file mode 100644 index 0000000000..b6de719e4d --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/yang/referenced-module.yang @@ -0,0 +1,13 @@ +module referenced-module { + namespace "referenced:module"; + + prefix "refmodule"; + revision 2014-04-17 { + } + + container cont { + leaf lf1 { + type instance-identifier; + } + } +} \ No newline at end of file