BUG 8927: Netconf response payload fails to render in JSON 84/63984/13
authorTomas Cere <tcere@cisco.com>
Tue, 3 Oct 2017 10:36:26 +0000 (12:36 +0200)
committerRobert Varga <nite@hq.sk>
Thu, 19 Oct 2017 15:51:15 +0000 (15:51 +0000)
JSONNormalizedNodeStreamWriter does not write a content of anyXml nodes
correctly mainly due to Text nodes containing whitespaces before, between
or after Element nodes. Therefore the first Text node only was serialized
to JSON and the rest of anyXML content was missing.
This patch provides fix of anyXml content serialization to JSON.

Change-Id: I74f34aecec1a85b2ede4be63e5b6dd74522981e4
Signed-off-by: Peter Kajsa <pkajsa@cisco.com>
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONNormalizedNodeStreamWriter.java
yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/AnyXmlSupportTest.java
yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/TestUtils.java
yang/yang-data-codec-gson/src/test/resources/bug8927/json/expected.json [new file with mode: 0644]
yang/yang-data-codec-gson/src/test/resources/bug8927/xml/input.xml [new file with mode: 0644]
yang/yang-data-codec-gson/src/test/resources/complexjson/yang/bug8927.yang [new file with mode: 0644]

index 568c14a87e8b24cf8d777574a91f30c6550794a5..c8be2cbdb6b8edfe5b27dd6fb11f4a842a7a89a2 100644 (file)
@@ -29,8 +29,10 @@ import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
 
 /**
  * This implementation will create JSON output as output stream.
@@ -272,77 +274,84 @@ public abstract class JSONNormalizedNodeStreamWriter implements NormalizedNodeSt
     }
 
     private void writeAnyXmlValue(final DOMSource anyXmlValue) throws IOException {
-        final Node documentNode = anyXmlValue.getNode();
-        final Node firstChild = documentNode.getFirstChild();
-        if (ELEMENT_NODE == firstChild.getNodeType() && !ANYXML_ARRAY_ELEMENT_ID.equals(firstChild.getNodeName())) {
+        writeXmlNode(anyXmlValue.getNode());
+    }
+
+    private void writeXmlNode(final Node node) throws IOException {
+        final Element firstChildElement = getFirstChildElement(node);
+        if (firstChildElement == null) {
+            writeXmlValue(node);
+        } else if (ANYXML_ARRAY_ELEMENT_ID.equals(firstChildElement.getNodeName())) {
+            writer.beginArray();
+            writeArray(firstChildElement);
+            writer.endArray();
+        } else {
             writer.beginObject();
-            traverseAnyXmlValue(documentNode);
+            writeObject(firstChildElement);
             writer.endObject();
-        } else {
-            traverseAnyXmlValue(documentNode);
         }
     }
 
-    private void traverseAnyXmlValue(final Node node) throws IOException {
-        final NodeList children = node.getChildNodes();
-        boolean inArray = false;
-
-        for (int i = 0, length = children.getLength(); i < length; i++) {
-            final Node childNode = children.item(i);
-            boolean inObject = false;
-
-            if (ELEMENT_NODE == childNode.getNodeType()) {
-                final Node firstChild = childNode.getFirstChild();
-                // beginning of an array
-                if (ANYXML_ARRAY_ELEMENT_ID.equals(childNode.getNodeName()) && !inArray) {
-                    writer.beginArray();
-                    inArray = true;
-                    // object at the beginning of the array
-                    if (isJsonObjectInArray(childNode, firstChild)) {
-                        writer.beginObject();
-                        inObject = true;
-                    }
-                    // object in the array
-                } else if (isJsonObjectInArray(childNode, firstChild)) {
-                    writer.beginObject();
-                    inObject = true;
-                    // object
-                } else if (isJsonObject(firstChild)) {
-                    writer.name(childNode.getNodeName());
-                    writer.beginObject();
-                    inObject = true;
-                    // name
-                } else if (!inArray) {
-                    writer.name(childNode.getNodeName());
-                }
+    private void writeArray(Node node) throws IOException {
+        while (node != null) {
+            if (ELEMENT_NODE == node.getNodeType()) {
+                writeXmlNode(node);
             }
+            node = node.getNextSibling();
+        }
+    }
 
-            // text value, i.e. a number, string, boolean or null
-            if (TEXT_NODE == childNode.getNodeType()) {
-                final String childNodeText = childNode.getNodeValue();
-                if (NUMBER_PATTERN.matcher(childNodeText).matches()) {
-                    writer.value(parseNumber(childNodeText));
-                } else if ("true".equals(childNodeText) || "false".equals(childNodeText)) {
-                    writer.value(Boolean.parseBoolean(childNodeText));
-                } else if ("null".equals(childNodeText)) {
-                    writer.nullValue();
-                } else {
-                    writer.value(childNodeText);
-                }
-
-                return;
+    private void writeObject(Node node) throws IOException {
+        while (node != null) {
+            if (ELEMENT_NODE == node.getNodeType()) {
+                writer.name(node.getNodeName());
+                writeXmlNode(node);
             }
+            node = node.getNextSibling();
+        }
+    }
 
-            traverseAnyXmlValue(childNode);
+    private void writeXmlValue(final Node node) throws IOException {
+        final String childNodeText = getFirstChildText(node).getWholeText().trim();
+        if (NUMBER_PATTERN.matcher(childNodeText).matches()) {
+            writer.value(parseNumber(childNodeText));
+            return;
+        }
+        switch (childNodeText) {
+            case "null":
+                writer.nullValue();
+                break;
+            case "false":
+                writer.value(false);
+                break;
+            case "true":
+                writer.value(true);
+                break;
+            default:
+                writer.value(childNodeText);
+        }
+    }
 
-            if (inObject) {
-                writer.endObject();
+    private static Element getFirstChildElement(final Node node) {
+        final NodeList children = node.getChildNodes();
+        for (int i = 0, length = children.getLength(); i < length; i++) {
+            final Node childNode = children.item(i);
+            if (ELEMENT_NODE == childNode.getNodeType()) {
+                return (Element) childNode;
             }
         }
+        return null;
+    }
 
-        if (inArray) {
-            writer.endArray();
+    private static Text getFirstChildText(final Node node) {
+        final NodeList children = node.getChildNodes();
+        for (int i = 0, length = children.getLength(); i < length; i++) {
+            final Node childNode = children.item(i);
+            if (TEXT_NODE == childNode.getNodeType()) {
+                return (Text) childNode;
+            }
         }
+        return null;
     }
 
     // json numbers are 64 bit wide floating point numbers - in java terms it is either long or double
@@ -353,14 +362,4 @@ public abstract class JSONNormalizedNodeStreamWriter implements NormalizedNodeSt
 
         return Double.valueOf(numberText);
     }
-
-    private static boolean isJsonObject(final Node firstChild) {
-        return !ANYXML_ARRAY_ELEMENT_ID.equals(firstChild.getNodeName()) && TEXT_NODE != firstChild.getNodeType();
-    }
-
-    private static boolean isJsonObjectInArray(final Node node, final Node firstChild) {
-        return ANYXML_ARRAY_ELEMENT_ID.equals(node.getNodeName())
-                && !ANYXML_ARRAY_ELEMENT_ID.equals(firstChild.getNodeName())
-                && TEXT_NODE != firstChild.getNodeType();
-    }
 }
index 28ffdb8a7ece08f5d1fc76a7b39ae24f072ca034..bac5a4144c1a1ebbe55a489f0a82c36211ce1a44 100644 (file)
@@ -8,18 +8,23 @@
 
 package org.opendaylight.yangtools.yang.data.codec.gson;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.opendaylight.yangtools.yang.data.codec.gson.TestUtils.loadTextFile;
+import static org.opendaylight.yangtools.yang.data.codec.gson.TestUtils.loadXmlToNormalizedNodes;
+import static org.opendaylight.yangtools.yang.data.codec.gson.TestUtils.normalizedNodesToJsonString;
 
 import com.google.gson.JsonElement;
 import com.google.gson.JsonParser;
 import com.google.gson.stream.JsonReader;
+import java.io.File;
+import java.io.FileReader;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.StringReader;
-import java.io.StringWriter;
-import java.io.Writer;
 import java.net.URISyntaxException;
+import java.util.Optional;
 import javax.xml.transform.dom.DOMSource;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -32,7 +37,6 @@ import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 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.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
 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;
@@ -83,15 +87,8 @@ public class AnyXmlSupportTest {
         final DOMSource Lf14AnyExpectedValue = createAnyXmlSimpleValue("ns:complex:json", "lf14-any", "null");
         verifyTransformedAnyXmlNodeValue(Lf14AnyExpectedValue, Lf14AnyActualValue);
 
-        // serialization
-        final Writer writer = new StringWriter();
-        final NormalizedNodeStreamWriter jsonStream = JSONNormalizedNodeStreamWriter.createExclusiveWriter(
-            JSONCodecFactory.getShared(schemaContext), SchemaPath.ROOT, null,
-            JsonWriterFactory.createJsonWriter(writer, 2));
-        final NormalizedNodeWriter nodeWriter = NormalizedNodeWriter.forStreamWriter(jsonStream);
-        nodeWriter.write(transformedInput);
-        nodeWriter.close();
-        final String serializationResult = writer.toString();
+        final String serializationResult = normalizedNodesToJsonString(transformedInput, schemaContext,
+                SchemaPath.ROOT);
 
         final JsonParser parser = new JsonParser();
         final JsonElement expected = parser.parse(inputJson);
@@ -126,14 +123,8 @@ public class AnyXmlSupportTest {
         verifyTransformedAnyXmlNodeValue(Lf14AnyExpectedValue, Lf14AnyActualValue);
 
         // serialization
-        final Writer writer = new StringWriter();
-        final NormalizedNodeStreamWriter jsonStream = JSONNormalizedNodeStreamWriter.createExclusiveWriter(
-            JSONCodecFactory.getShared(schemaContext), SchemaPath.ROOT, null,
-            JsonWriterFactory.createJsonWriter(writer, 2));
-        final NormalizedNodeWriter nodeWriter = NormalizedNodeWriter.forStreamWriter(jsonStream);
-        nodeWriter.write(transformedInput);
-        nodeWriter.close();
-        final String serializationResult = writer.toString();
+        final String serializationResult = normalizedNodesToJsonString(transformedInput, schemaContext,
+                SchemaPath.ROOT);
 
         final JsonParser parser = new JsonParser();
         final JsonElement expected = parser.parse(inputJson);
@@ -141,6 +132,29 @@ public class AnyXmlSupportTest {
         assertTrue(expected.equals(actual));
     }
 
+    @Test
+    public void bug8927Test() throws Exception {
+        final InputStream resourceAsStream = YangModeledAnyXmlSupportTest.class
+                .getResourceAsStream("/bug8927/xml/input.xml");
+        final NormalizedNodeResult result = new NormalizedNodeResult();
+        loadXmlToNormalizedNodes(resourceAsStream, result, schemaContext);
+
+        assertNotNull(result.getResult());
+        assertTrue(result.getResult() instanceof ContainerNode);
+
+        final Optional<DataContainerChild<? extends PathArgument, ?>> data = ((ContainerNode) result.getResult())
+                .getChild(new NodeIdentifier(QName.create("bug8927.test", "2017-01-01", "foo")));
+        assertTrue(data.isPresent());
+        final String jsonOutput = normalizedNodesToJsonString(data.get(), schemaContext, SchemaPath.ROOT);
+
+        final JsonParser parser = new JsonParser();
+        final JsonElement expextedJson = parser
+                .parse(new FileReader(new File(getClass().getResource("/bug8927/json/expected.json").toURI())));
+        final JsonElement serializedJson = parser.parse(jsonOutput);
+
+        assertEquals(expextedJson, serializedJson);
+    }
+
     private static DOMSource getParsedAnyXmlValue(final NormalizedNode<?, ?> transformedInput, final QName anyxmlName) {
         assertTrue(transformedInput instanceof ContainerNode);
         final ContainerNode cont1 = (ContainerNode) transformedInput;
index acedf94cf1675022d89a1318fe19f20a78aef0b5..a8c512301ff2ee66f72bf1a0f1107f7c8841a97c 100644 (file)
@@ -18,7 +18,20 @@ import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.io.Writer;
 import java.net.URISyntaxException;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
+import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream;
+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.model.api.SchemaPath;
 
 public final class TestUtils {
 
@@ -27,11 +40,11 @@ public final class TestUtils {
     }
 
     static String loadTextFile(final File file) throws IOException {
-        FileReader fileReader = new FileReader(file);
-        BufferedReader bufReader = new BufferedReader(fileReader);
+        final FileReader fileReader = new FileReader(file);
+        final BufferedReader bufReader = new BufferedReader(fileReader);
 
         String line = null;
-        StringBuilder result = new StringBuilder();
+        final StringBuilder result = new StringBuilder();
         while ((line = bufReader.readLine()) != null) {
             result.append(line);
         }
@@ -43,9 +56,31 @@ public final class TestUtils {
         return loadTextFile(new File(TestUtils.class.getResource(relativePath).toURI()));
     }
 
+    static void loadXmlToNormalizedNodes(final InputStream xmlInputStream, final NormalizedNodeResult result,
+            final SchemaContext schemaContext) throws Exception {
+        final XMLInputFactory factory = XMLInputFactory.newInstance();
+        final XMLStreamReader reader = factory.createXMLStreamReader(xmlInputStream);
+        final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
+        final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, schemaContext, schemaContext);
+        xmlParser.parse(reader);
+    }
+
+    static String normalizedNodesToJsonString(final NormalizedNode<?, ?> data, final SchemaContext schemaContext,
+            final SchemaPath rootPath) throws IOException {
+        final Writer writer = new StringWriter();
+        final NormalizedNodeStreamWriter jsonStream = JSONNormalizedNodeStreamWriter.createExclusiveWriter(
+                JSONCodecFactory.getShared(schemaContext), rootPath, null,
+                JsonWriterFactory.createJsonWriter(writer, 2));
+        final NormalizedNodeWriter nodeWriter = NormalizedNodeWriter.forStreamWriter(jsonStream);
+        nodeWriter.write(data);
+        nodeWriter.close();
+        final String serializationResult = writer.toString();
+        return serializationResult;
+    }
+
     static JsonObject childObject(final JsonObject jsonObject, final String... names) {
-        for (String name : names) {
-            JsonObject childJsonObject = jsonObject.getAsJsonObject(name);
+        for (final String name : names) {
+            final JsonObject childJsonObject = jsonObject.getAsJsonObject(name);
             if (childJsonObject != null) {
                 return childJsonObject;
             }
@@ -54,8 +89,8 @@ public final class TestUtils {
     }
 
     static JsonPrimitive childPrimitive(final JsonObject jsonObject, final String... names) {
-        for (String name : names) {
-            JsonPrimitive childJsonPrimitive = jsonObject.getAsJsonPrimitive(name);
+        for (final String name : names) {
+            final JsonPrimitive childJsonPrimitive = jsonObject.getAsJsonPrimitive(name);
             if (childJsonPrimitive != null) {
                 return childJsonPrimitive;
             }
@@ -64,8 +99,8 @@ public final class TestUtils {
     }
 
     static JsonArray childArray(final JsonObject jsonObject, final String... names) {
-        for (String name : names) {
-            JsonArray childJsonArray = jsonObject.getAsJsonArray(name);
+        for (final String name : names) {
+            final JsonArray childJsonArray = jsonObject.getAsJsonArray(name);
             if (childJsonArray != null) {
                 return childJsonArray;
             }
@@ -73,12 +108,12 @@ public final class TestUtils {
         return null;
     }
 
-    static JsonObject resolveCont1(String jsonOutput) {
-        JsonParser parser = new JsonParser();
-        JsonElement rootElement = parser.parse(jsonOutput);
+    static JsonObject resolveCont1(final String jsonOutput) {
+        final JsonParser parser = new JsonParser();
+        final JsonElement rootElement = parser.parse(jsonOutput);
         assertTrue(rootElement.isJsonObject());
-        JsonObject rootObject = rootElement.getAsJsonObject();
-        JsonObject cont1 = childObject(rootObject, "complexjson:cont1", "cont1");
+        final JsonObject rootObject = rootElement.getAsJsonObject();
+        final JsonObject cont1 = childObject(rootObject, "complexjson:cont1", "cont1");
         return cont1;
     }
 
diff --git a/yang/yang-data-codec-gson/src/test/resources/bug8927/json/expected.json b/yang/yang-data-codec-gson/src/test/resources/bug8927/json/expected.json
new file mode 100644 (file)
index 0000000..396f2be
--- /dev/null
@@ -0,0 +1,121 @@
+{
+  "bug8927:foo": {
+    "alarm-information": {
+      "alarm-summary": {
+        "active-alarm-count": 16
+      },
+      "alarm-detail": {
+        "alarm-time": "2017-08-02 19:03:44 UTC",
+        "alarm-class": "Minor",
+        "alarm-description": "desc",
+        "alarm-short-description": "gnf-creation",
+        "alarm-type": "License"
+      },
+      "alarm-detail": {
+        "alarm-time": "2017-07-25 16:04:31 UTC",
+        "alarm-class": "Minor",
+        "alarm-description": "VMHost RE 0 host application failed",
+        "alarm-short-description": "VMHost RE 0 host ap",
+        "alarm-type": "Chassis"
+      },
+      "alarm-detail": {
+        "alarm-time": "2017-07-25 16:04:31 UTC",
+        "alarm-class": "Major",
+        "alarm-description": "PDM 0 incompatible with chassis type",
+        "alarm-short-description": "PDM 0 incompatible",
+        "alarm-type": "Chassis"
+      },
+      "alarm-detail": {
+        "alarm-time": "2017-07-25 16:04:31 UTC",
+        "alarm-class": "Major",
+        "alarm-description": "PDM 1 incompatible with chassis type",
+        "alarm-short-description": "PDM 1 incompatible",
+        "alarm-type": "Chassis"
+      },
+      "alarm-detail": {
+        "alarm-time": "2017-07-25 16:04:31 UTC",
+        "alarm-class": "Major",
+        "alarm-description": "PDM 2 incompatible with chassis type",
+        "alarm-short-description": "PDM 2 incompatible",
+        "alarm-type": "Chassis"
+      },
+      "alarm-detail": {
+        "alarm-time": "2017-07-25 16:04:31 UTC",
+        "alarm-class": "Major",
+        "alarm-description": "PDM 3 incompatible with chassis type",
+        "alarm-short-description": "PDM 3 incompatible",
+        "alarm-type": "Chassis"
+      },
+      "alarm-detail": {
+        "alarm-time": "2017-07-25 16:04:31 UTC",
+        "alarm-class": "Major",
+        "alarm-description": "No Input Feed Selected for PSM 1",
+        "alarm-short-description": "No Input Feed Selec",
+        "alarm-type": "Chassis"
+      },
+      "alarm-detail": {
+        "alarm-time": "2017-07-25 16:04:31 UTC",
+        "alarm-class": "Major",
+        "alarm-description": "No Input Feed Selected for PSM 2",
+        "alarm-short-description": "No Input Feed Selec",
+        "alarm-type": "Chassis"
+      },
+      "alarm-detail": {
+        "alarm-time": "2017-07-25 16:04:31 UTC",
+        "alarm-class": "Major",
+        "alarm-description": "No Input Feed Selected for PSM 3",
+        "alarm-short-description": "No Input Feed Selec",
+        "alarm-type": "Chassis"
+      },
+      "alarm-detail": {
+        "alarm-time": "2017-07-25 16:04:31 UTC",
+        "alarm-class": "Major",
+        "alarm-description": "No Input Feed Selected for PSM 4",
+        "alarm-short-description": "No Input Feed Selec",
+        "alarm-type": "Chassis"
+      },
+      "alarm-detail": {
+        "alarm-time": "2017-07-25 16:04:31 UTC",
+        "alarm-class": "Major",
+        "alarm-description": "No Input Feed Selected for PSM 10",
+        "alarm-short-description": "No Input Feed Selec",
+        "alarm-type": "Chassis"
+      },
+      "alarm-detail": {
+        "alarm-time": "2017-07-25 16:04:31 UTC",
+        "alarm-class": "Major",
+        "alarm-description": "No Input Feed Selected for PSM 11",
+        "alarm-short-description": "No Input Feed Selec",
+        "alarm-type": "Chassis"
+      },
+      "alarm-detail": {
+        "alarm-time": "2017-07-25 16:04:31 UTC",
+        "alarm-class": "Major",
+        "alarm-description": "No Input Feed Selected for PSM 12",
+        "alarm-short-description": "No Input Feed Selec",
+        "alarm-type": "Chassis"
+      },
+      "alarm-detail": {
+        "alarm-time": "2017-07-25 16:04:31 UTC",
+        "alarm-class": "Major",
+        "alarm-description": "No Input Feed Selected for PSM 13",
+        "alarm-short-description": "No Input Feed Selec",
+        "alarm-type": "Chassis"
+      },
+      "alarm-detail": {
+        "alarm-time": "2017-07-25 16:04:31 UTC",
+        "alarm-class": "Minor",
+        "alarm-description": "VMHost RE 1 host application failed",
+        "alarm-short-description": "VMHost RE 1 host ap",
+        "alarm-type": "Chassis"
+      },
+      "alarm-detail": {
+        "alarm-time": "2017-07-25 16:04:31 UTC",
+        "alarm-class": "Minor",
+        "alarm-description": "Check plane 1 Fabric Chip",
+        "alarm-short-description": "Check plane 1 FCHIP",
+        "alarm-type": "Chassis"
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/yang/yang-data-codec-gson/src/test/resources/bug8927/xml/input.xml b/yang/yang-data-codec-gson/src/test/resources/bug8927/xml/input.xml
new file mode 100644 (file)
index 0000000..24f01e1
--- /dev/null
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root>
+<foo xmlns="bug8927.test">
+    <alarm-information xmlns="bug8927.test">
+        <alarm-summary>
+            <active-alarm-count>16</active-alarm-count>
+        </alarm-summary>
+        <alarm-detail>
+            <alarm-time>
+                2017-08-02 19:03:44 UTC
+            </alarm-time>
+            <alarm-class>Minor</alarm-class>
+            <alarm-description>desc</alarm-description>
+            <alarm-short-description>gnf-creation</alarm-short-description>
+            <alarm-type>License</alarm-type>
+        </alarm-detail>
+        <alarm-detail>
+            <alarm-time>
+                2017-07-25 16:04:31 UTC
+            </alarm-time>
+            <alarm-class>Minor</alarm-class>
+            <alarm-description>VMHost RE 0 host application failed</alarm-description>
+            <alarm-short-description>VMHost RE 0 host ap</alarm-short-description>
+            <alarm-type>Chassis</alarm-type>
+        </alarm-detail>
+        <alarm-detail>
+            <alarm-time>
+                2017-07-25 16:04:31 UTC
+            </alarm-time>
+            <alarm-class>Major</alarm-class>
+            <alarm-description>PDM 0 incompatible with chassis type</alarm-description>
+            <alarm-short-description>PDM 0 incompatible</alarm-short-description>
+            <alarm-type>Chassis</alarm-type>
+        </alarm-detail>
+        <alarm-detail>
+            <alarm-time>
+                2017-07-25 16:04:31 UTC
+            </alarm-time>
+            <alarm-class>Major</alarm-class>
+            <alarm-description>PDM 1 incompatible with chassis type</alarm-description>
+            <alarm-short-description>PDM 1 incompatible</alarm-short-description>
+            <alarm-type>Chassis</alarm-type>
+        </alarm-detail>
+        <alarm-detail>
+            <alarm-time>
+                2017-07-25 16:04:31 UTC
+            </alarm-time>
+            <alarm-class>Major</alarm-class>
+            <alarm-description>PDM 2 incompatible with chassis type</alarm-description>
+            <alarm-short-description>PDM 2 incompatible</alarm-short-description>
+            <alarm-type>Chassis</alarm-type>
+        </alarm-detail>
+        <alarm-detail>
+            <alarm-time>
+                2017-07-25 16:04:31 UTC
+            </alarm-time>
+            <alarm-class>Major</alarm-class>
+            <alarm-description>PDM 3 incompatible with chassis type</alarm-description>
+            <alarm-short-description>PDM 3 incompatible</alarm-short-description>
+            <alarm-type>Chassis</alarm-type>
+        </alarm-detail>
+        <alarm-detail>
+            <alarm-time>
+                2017-07-25 16:04:31 UTC
+            </alarm-time>
+            <alarm-class>Major</alarm-class>
+            <alarm-description>No Input Feed Selected for PSM 1</alarm-description>
+            <alarm-short-description>No Input Feed Selec</alarm-short-description>
+            <alarm-type>Chassis</alarm-type>
+        </alarm-detail>
+        <alarm-detail>
+            <alarm-time>
+                2017-07-25 16:04:31 UTC
+            </alarm-time>
+            <alarm-class>Major</alarm-class>
+            <alarm-description>No Input Feed Selected for PSM 2</alarm-description>
+            <alarm-short-description>No Input Feed Selec</alarm-short-description>
+            <alarm-type>Chassis</alarm-type>
+        </alarm-detail>
+        <alarm-detail>
+            <alarm-time>
+                2017-07-25 16:04:31 UTC
+            </alarm-time>
+            <alarm-class>Major</alarm-class>
+            <alarm-description>No Input Feed Selected for PSM 3</alarm-description>
+            <alarm-short-description>No Input Feed Selec</alarm-short-description>
+            <alarm-type>Chassis</alarm-type>
+        </alarm-detail>
+        <alarm-detail>
+            <alarm-time>
+                2017-07-25 16:04:31 UTC
+            </alarm-time>
+            <alarm-class>Major</alarm-class>
+            <alarm-description>No Input Feed Selected for PSM 4</alarm-description>
+            <alarm-short-description>No Input Feed Selec</alarm-short-description>
+            <alarm-type>Chassis</alarm-type>
+        </alarm-detail>
+        <alarm-detail>
+            <alarm-time>
+                2017-07-25 16:04:31 UTC
+            </alarm-time>
+            <alarm-class>Major</alarm-class>
+            <alarm-description>No Input Feed Selected for PSM 10</alarm-description>
+            <alarm-short-description>No Input Feed Selec</alarm-short-description>
+            <alarm-type>Chassis</alarm-type>
+        </alarm-detail>
+        <alarm-detail>
+            <alarm-time>
+                2017-07-25 16:04:31 UTC
+            </alarm-time>
+            <alarm-class>Major</alarm-class>
+            <alarm-description>No Input Feed Selected for PSM 11</alarm-description>
+            <alarm-short-description>No Input Feed Selec</alarm-short-description>
+            <alarm-type>Chassis</alarm-type>
+        </alarm-detail>
+        <alarm-detail>
+            <alarm-time>
+                2017-07-25 16:04:31 UTC
+            </alarm-time>
+            <alarm-class>Major</alarm-class>
+            <alarm-description>No Input Feed Selected for PSM 12</alarm-description>
+            <alarm-short-description>No Input Feed Selec</alarm-short-description>
+            <alarm-type>Chassis</alarm-type>
+        </alarm-detail>
+        <alarm-detail>
+            <alarm-time>
+                2017-07-25 16:04:31 UTC
+            </alarm-time>
+            <alarm-class>Major</alarm-class>
+            <alarm-description>No Input Feed Selected for PSM 13</alarm-description>
+            <alarm-short-description>No Input Feed Selec</alarm-short-description>
+            <alarm-type>Chassis</alarm-type>
+        </alarm-detail>
+        <alarm-detail>
+            <alarm-time>
+                2017-07-25 16:04:31 UTC
+            </alarm-time>
+            <alarm-class>Minor</alarm-class>
+            <alarm-description>VMHost RE 1 host application failed</alarm-description>
+            <alarm-short-description>VMHost RE 1 host ap</alarm-short-description>
+            <alarm-type>Chassis</alarm-type>
+        </alarm-detail>
+        <alarm-detail>
+            <alarm-time>
+                2017-07-25 16:04:31 UTC
+            </alarm-time>
+            <alarm-class>Minor</alarm-class>
+            <alarm-description>Check plane 1 Fabric Chip</alarm-description>
+            <alarm-short-description>Check plane 1 FCHIP</alarm-short-description>
+            <alarm-type>Chassis</alarm-type>
+        </alarm-detail>
+    </alarm-information>
+</foo>
+</root>
\ No newline at end of file
diff --git a/yang/yang-data-codec-gson/src/test/resources/complexjson/yang/bug8927.yang b/yang/yang-data-codec-gson/src/test/resources/complexjson/yang/bug8927.yang
new file mode 100644 (file)
index 0000000..05637fd
--- /dev/null
@@ -0,0 +1,12 @@
+module bug8927 {
+    namespace "bug8927.test";
+    prefix tst;
+
+    revision 2017-01-01 {
+    }
+
+    container foo {
+        anyxml alarm-information;
+    }
+}
+