Bug 4501 - JSON for "type bits" in YANG models not handled correctly 14/28614/4
authorPeter Kajsa <pkajsa@cisco.com>
Tue, 20 Oct 2015 15:38:13 +0000 (17:38 +0200)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 9 Nov 2015 12:28:35 +0000 (12:28 +0000)
- rejecting of value rewrite (quickfix)

Change-Id: I1007b15d5beacff2877137173fa09e009b877c57
Signed-off-by: Peter Kajsa <pkajsa@cisco.com>
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JsonParserStream.java
yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/retest/Bug4501Test.java [new file with mode: 0644]
yang/yang-data-codec-gson/src/test/resources/bug-4501/json/foo-correct.json [new file with mode: 0644]
yang/yang-data-codec-gson/src/test/resources/bug-4501/json/foo-incorrect.json [new file with mode: 0644]
yang/yang-data-codec-gson/src/test/resources/bug-4501/yang/foo.yang [new file with mode: 0644]

index e44b5989fd74d7762296c501d448c916a4ba18b6..aeb05df10a3f3c808e550bd1af19a05b5ba24ef1 100644 (file)
@@ -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 (file)
index 0000000..0e9ff9b
--- /dev/null
@@ -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<DataContainerChild<? extends PathArgument, ?>> lrsBits = hop.getChild(0).getChild(
+                NodeIdentifier.create(QName.create("foo", "1970-01-01", "lrs-bits")));
+
+        final ImmutableSet<String> 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 (file)
index 0000000..a650d28
--- /dev/null
@@ -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 (file)
index 0000000..e2b3b4c
--- /dev/null
@@ -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 (file)
index 0000000..8a1d060
--- /dev/null
@@ -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.";
+        }
+    }
+}