From 0ce1df6bdbd80e891aaf42ce4a9068025ec72a3a Mon Sep 17 00:00:00 2001 From: Peter Kajsa Date: Tue, 20 Oct 2015 17:38:13 +0200 Subject: [PATCH] Bug 4501 - JSON for "type bits" in YANG models not handled correctly - rejecting of value rewrite (quickfix) Change-Id: I1007b15d5beacff2877137173fa09e009b877c57 Signed-off-by: Peter Kajsa --- .../data/codec/gson/JsonParserStream.java | 12 ++- .../data/codec/gson/retest/Bug4501Test.java | 79 +++++++++++++++++++ .../resources/bug-4501/json/foo-correct.json | 16 ++++ .../bug-4501/json/foo-incorrect.json | 16 ++++ .../src/test/resources/bug-4501/yang/foo.yang | 30 +++++++ 5 files changed, 149 insertions(+), 4 deletions(-) create mode 100644 yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/retest/Bug4501Test.java create mode 100644 yang/yang-data-codec-gson/src/test/resources/bug-4501/json/foo-correct.json create mode 100644 yang/yang-data-codec-gson/src/test/resources/bug-4501/json/foo-incorrect.json create mode 100644 yang/yang-data-codec-gson/src/test/resources/bug-4501/yang/foo.yang diff --git a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JsonParserStream.java b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JsonParserStream.java index e44b5989fd..aeb05df10a 100644 --- a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JsonParserStream.java +++ b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JsonParserStream.java @@ -105,10 +105,14 @@ public final class JsonParserStream implements Closeable, Flushable { } private void setValue(final AbstractNodeDataWithSchema parent, final String value) { - Preconditions.checkArgument(parent instanceof SimpleNodeDataWithSchema, "Node %s is not a simple type", parent.getSchema().getQName()); - - final Object translatedValue = translateValueByType(value, parent.getSchema()); - ((SimpleNodeDataWithSchema) parent).setValue(translatedValue); + Preconditions.checkArgument(parent instanceof SimpleNodeDataWithSchema, "Node %s is not a simple type", + parent.getSchema().getQName()); + final SimpleNodeDataWithSchema parentSimpleNode = (SimpleNodeDataWithSchema) parent; + Preconditions.checkArgument(parentSimpleNode.getValue() == null, "Node '%s' has already set its value to '%s'", + parentSimpleNode.getSchema().getQName(), parentSimpleNode.getValue()); + + final Object translatedValue = translateValueByType(value, parentSimpleNode.getSchema()); + parentSimpleNode.setValue(translatedValue); } public void read(final JsonReader in, AbstractNodeDataWithSchema parent) throws IOException { diff --git a/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/retest/Bug4501Test.java b/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/retest/Bug4501Test.java new file mode 100644 index 0000000000..0e9ff9b95b --- /dev/null +++ b/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/retest/Bug4501Test.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2015 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.yangtools.yang.data.codec.gson.retest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; +import static org.opendaylight.yangtools.yang.data.codec.gson.retest.TestUtils.loadModules; +import static org.opendaylight.yangtools.yang.data.codec.gson.retest.TestUtils.loadTextFile; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; +import com.google.gson.stream.JsonReader; +import java.io.IOException; +import java.io.StringReader; +import java.net.URISyntaxException; +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode; +import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.codec.gson.JsonParserStream; +import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; + +public class Bug4501Test { + + private static SchemaContext schemaContext; + + @BeforeClass + public static void initialization() throws IOException, URISyntaxException, ReactorException { + schemaContext = loadModules("/bug-4501/yang"); + } + + @Test + public void testCorrectInput() throws IOException, URISyntaxException { + final String inputJson = loadTextFile("/bug-4501/json/foo-correct.json"); + final NormalizedNodeResult result = new NormalizedNodeResult(); + final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result); + final JsonParserStream jsonParser = JsonParserStream.create(streamWriter, schemaContext); + jsonParser.parse(new JsonReader(new StringReader(inputJson))); + final NormalizedNode transformedInput = result.getResult(); + assertNotNull(transformedInput instanceof UnkeyedListNode); + + final UnkeyedListNode hop = (UnkeyedListNode) transformedInput; + final Optional> lrsBits = hop.getChild(0).getChild( + NodeIdentifier.create(QName.create("foo", "1970-01-01", "lrs-bits"))); + + final ImmutableSet expectedValue = ImmutableSet.of("lookup", "rloc-probe", "strict"); + assertEquals(expectedValue, lrsBits.get().getValue()); + } + + @Test + public void testIncorrectInput() throws IOException, URISyntaxException { + final String inputJson = loadTextFile("/bug-4501/json/foo-incorrect.json"); + final NormalizedNodeResult result = new NormalizedNodeResult(); + final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result); + final JsonParserStream jsonParser = JsonParserStream.create(streamWriter, schemaContext); + + try { + jsonParser.parse(new JsonReader(new StringReader(inputJson))); + fail("IllegalArgumentException should be thrown."); + } catch (IllegalArgumentException e) { + assertEquals(e.getMessage(), + "Node '(foo?revision=1970-01-01)lrs-bits' has already set its value to '[lookup]'"); + } + } +} \ No newline at end of file diff --git a/yang/yang-data-codec-gson/src/test/resources/bug-4501/json/foo-correct.json b/yang/yang-data-codec-gson/src/test/resources/bug-4501/json/foo-correct.json new file mode 100644 index 0000000000..a650d28003 --- /dev/null +++ b/yang/yang-data-codec-gson/src/test/resources/bug-4501/json/foo-correct.json @@ -0,0 +1,16 @@ +{ + "hop": [ + { + "address": "192.0.2.1", + "lrs-bits": "lookup rloc-probe strict" + }, + { + "address": "192.0.2.2", + "lrs-bits": "lookup rloc-probe" + }, + { + "address": "192.0.2.3", + "lrs-bits": "lookup rloc-probe strict" + } + ] +} diff --git a/yang/yang-data-codec-gson/src/test/resources/bug-4501/json/foo-incorrect.json b/yang/yang-data-codec-gson/src/test/resources/bug-4501/json/foo-incorrect.json new file mode 100644 index 0000000000..e2b3b4c60e --- /dev/null +++ b/yang/yang-data-codec-gson/src/test/resources/bug-4501/json/foo-incorrect.json @@ -0,0 +1,16 @@ +{ + "hop": [ + { + "address": "192.0.2.1", + "lrs-bits": ["lookup", "rloc-probe", "strict"] + }, + { + "address": "192.0.2.2", + "lrs-bits": ["lookup", "rloc-probe"] + }, + { + "address": "192.0.2.3", + "lrs-bits": ["lookup", "rloc-probe", "strict"] + } + ] +} diff --git a/yang/yang-data-codec-gson/src/test/resources/bug-4501/yang/foo.yang b/yang/yang-data-codec-gson/src/test/resources/bug-4501/yang/foo.yang new file mode 100644 index 0000000000..8a1d0604da --- /dev/null +++ b/yang/yang-data-codec-gson/src/test/resources/bug-4501/yang/foo.yang @@ -0,0 +1,30 @@ +module foo { + namespace "foo"; + prefix foo; + yang-version 1; + + list hop { + leaf address { + type string; + } + + leaf lrs-bits { + type bits { + bit lookup { + description + "Lookup bit."; + } + bit rloc-probe { + description + "RLOC-probe bit."; + } + bit strict { + description + "Strict bit."; + } + } + description + "Flag bits per hop."; + } + } +} -- 2.36.6