BUG 484 Anyxml normalized node 62/8062/4
authorJozef Gloncak <jgloncak@cisco.com>
Mon, 16 Jun 2014 12:22:41 +0000 (14:22 +0200)
committerJozef Gloncak <jgloncak@cisco.com>
Tue, 24 Jun 2014 07:48:04 +0000 (09:48 +0200)
- DataNormalizationOperation: added AnyXmlNormalization for
  AnyXmlSchemaNode

- Moved DataNormalizerTest to sal-common-impl where the source code
  resides and added more tests including coverage for anyxml.

Originally commited under patch set 9
https://git.opendaylight.org/gerrit/#/c/7337/9 by Tom Pantelis

This commit depends (therefore is commited as draft) on commits:
- Add Anyxml normalized node to yang-data-api -
https://git.opendaylight.org/gerrit/#/c/7771/1
- Implementation of Anyxml builder -
  https://git.opendaylight.org/gerrit/#/c/8061/

Change-Id: I8f6febd1738cde3139cc32d8199d1a87c464ba34
Signed-off-by: Jozef Gloncak <jgloncak@cisco.com>
opendaylight/md-sal/sal-common-impl/pom.xml
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizationOperation.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizer.java
opendaylight/md-sal/sal-common-impl/src/test/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizerTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-common-impl/src/test/resources/normalization-test.yang [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/broker/impl/DataNormalizerTest.java [deleted file]

index 6b387b5a61cd206559e2cb11e43e53e3fe0d9ff5..82bd716c59c69c67a054e3a54cd554a85d9a3eac 100644 (file)
       <artifactId>mockito-all</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-parser-impl</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <build>
index a7c6b0c66fe4e688a9d868a89b7c761e64c962fc..7ce475dd59ea1a056ac8d5a85d751a33f6d9a17f 100644 (file)
@@ -10,6 +10,10 @@ package org.opendaylight.controller.md.sal.common.impl.util.compat;
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 
+import com.google.common.base.Optional;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
@@ -17,7 +21,6 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
-
 import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
@@ -28,12 +31,15 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
+import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
 import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
@@ -45,11 +51,6 @@ import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
-import com.google.common.base.Optional;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-
 public abstract class DataNormalizationOperation<T extends PathArgument> implements Identifiable<T> {
 
     private final T identifier;
@@ -612,6 +613,42 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
         }
     }
 
+    private static class AnyXmlNormalization extends DataNormalizationOperation<NodeIdentifier> {
+
+        protected AnyXmlNormalization( NodeIdentifier identifier ) {
+            super( identifier );
+        }
+
+        @Override
+        public DataNormalizationOperation<?> getChild( PathArgument child ) throws DataNormalizationException {
+            return null;
+        }
+
+        @Override
+        public DataNormalizationOperation<?> getChild( QName child ) throws DataNormalizationException {
+            return null;
+        }
+
+        @Override
+        public NormalizedNode<?, ?> normalize( Node<?> legacyData ) {
+            NormalizedNodeAttrBuilder<NodeIdentifier, Node<?>, AnyXmlNode> builder =
+                    Builders.anyXmlBuilder().withNodeIdentifier(
+                                                new NodeIdentifier( legacyData.getNodeType() ) );
+            builder.withValue(legacyData);
+            return builder.build();
+        }
+
+        @Override
+        public boolean isLeaf() {
+            return false;
+        }
+
+        @Override
+        public NormalizedNode<?, ?> createDefault( PathArgument currentArg ) {
+            return null;
+        }
+    }
+
     private static final Optional<DataSchemaNode> findChildSchemaNode(final DataNodeContainer parent,final QName child) {
         DataSchemaNode potential = parent.getDataChildByName(child);
         if (potential == null) {
@@ -712,6 +749,8 @@ public abstract class DataNormalizationOperation<T extends PathArgument> impleme
             return new ChoiceNodeNormalization((org.opendaylight.yangtools.yang.model.api.ChoiceNode) potential);
         } else if (potential instanceof LeafListSchemaNode) {
             return fromLeafListSchemaNode((LeafListSchemaNode) potential);
+        } else if (potential instanceof AnyXmlSchemaNode) {
+            return new AnyXmlNormalization( new NodeIdentifier(potential.getQName() ) );
         }
         return null;
     }
index f30c8ddcaabf5c8c7cff69744b9ee3e8f936ebf8..ec8ce6ecd5a96e628d2883ab38f24aaab383095a 100644 (file)
@@ -9,11 +9,15 @@ package org.opendaylight.controller.md.sal.common.impl.util.compat;
 
 import static com.google.common.base.Preconditions.checkArgument;
 
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicates;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
 import java.util.AbstractMap;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.Map;
-
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
@@ -21,6 +25,7 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationI
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MixinNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
@@ -31,12 +36,6 @@ import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl;
 import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicates;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-
 public class DataNormalizer {
 
     private final DataNormalizationOperation<?> operation;
@@ -134,6 +133,9 @@ public class DataNormalizer {
         // DataContainerNode<?>,"Node object %s, %s should be of type DataContainerNode",normalizedPath,normalizedData);
         if (normalizedData instanceof DataContainerNode<?>) {
             return toLegacyFromDataContainer((DataContainerNode<?>) normalizedData);
+        } else if (normalizedData instanceof AnyXmlNode) {
+            Node<?> value = ((AnyXmlNode) normalizedData).getValue();
+            return value instanceof CompositeNode ? (CompositeNode)value : null;
         }
         return null;
     }
@@ -150,6 +152,8 @@ public class DataNormalizer {
 
         if (node instanceof DataContainerNode<?>) {
             return toLegacyFromDataContainer((DataContainerNode<?>) node);
+        } else if (node instanceof AnyXmlNode) {
+            return ((AnyXmlNode) node).getValue();
         }
         return toLegacySimple(node);
 
diff --git a/opendaylight/md-sal/sal-common-impl/src/test/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizerTest.java b/opendaylight/md-sal/sal-common-impl/src/test/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizerTest.java
new file mode 100644 (file)
index 0000000..ddf089c
--- /dev/null
@@ -0,0 +1,768 @@
+/*
+ * Copyright (c) 2014 Brocade Communications 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.md.sal.common.impl.util.compat;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.OrderedLeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+
+public class DataNormalizerTest {
+
+    static class NormalizedNodeData {
+        PathArgument nodeID;
+        Class<?> nodeClass;
+        Object nodeData; // List for a container, value Object for a leaf
+
+        NormalizedNodeData(PathArgument nodeID, Class<?> nodeClass, Object nodeData) {
+            this.nodeID = nodeID;
+            this.nodeClass = nodeClass;
+            this.nodeData = nodeData;
+        }
+    }
+
+    static class LegacyNodeData {
+        QName nodeKey;
+        Object nodeData; // List for a CompositeNode, value Object for a
+                         // SimpeNode
+
+        LegacyNodeData(QName nodeKey, Object nodeData) {
+            this.nodeKey = nodeKey;
+            this.nodeData = nodeData;
+        }
+
+        @Override
+        public String toString() {
+            return nodeKey.toString();
+        }
+    }
+
+    static final QName TEST_QNAME = QName.create(
+            "urn:opendaylight:params:xml:ns:yang:controller:md:sal:normalization:test", "2014-03-13", "test");
+    static final QName OUTER_LIST_QNAME = QName.create(TEST_QNAME, "outer-list");
+    static final QName INNER_LIST_QNAME = QName.create(TEST_QNAME, "inner-list");
+    static final QName OUTER_CHOICE_QNAME = QName.create(TEST_QNAME, "outer-choice");
+    static final QName ID_QNAME = QName.create(TEST_QNAME, "id");
+    static final QName NAME_QNAME = QName.create(TEST_QNAME, "name");
+    static final QName VALUE_QNAME = QName.create(TEST_QNAME, "value");
+
+    static final InstanceIdentifier TEST_PATH = InstanceIdentifier.of(TEST_QNAME);
+    static final InstanceIdentifier OUTER_LIST_PATH = InstanceIdentifier.builder(TEST_PATH).node(OUTER_LIST_QNAME)
+            .build();
+    static final QName ONE_QNAME = QName.create(TEST_QNAME, "one");
+    static final QName TWO_QNAME = QName.create(TEST_QNAME, "two");
+    static final QName THREE_QNAME = QName.create(TEST_QNAME, "three");
+
+    static final QName ANY_XML_DATA_QNAME = QName.create(TEST_QNAME, "any-xml-data");
+    static final QName OUTER_CONTAINER_QNAME = QName.create(TEST_QNAME, "outer-container");
+    static final QName AUGMENTED_LEAF_QNAME = QName.create(TEST_QNAME, "augmented-leaf");
+    static final QName UNKEYED_LIST_QNAME = QName.create(TEST_QNAME, "unkeyed-list");
+    static final QName UNORDERED_LEAF_LIST_QNAME = QName.create(TEST_QNAME, "unordered-leaf-list");
+    static final QName ORDERED_LEAF_LIST_QNAME = QName.create(TEST_QNAME, "ordered-leaf-list");
+
+    static final Short OUTER_LIST_ID = (short) 10;
+
+    static final InstanceIdentifier OUTER_LIST_PATH_LEGACY = InstanceIdentifier.builder(TEST_QNAME)
+            .nodeWithKey(OUTER_LIST_QNAME, ID_QNAME, OUTER_LIST_ID).build();
+
+    static final InstanceIdentifier LEAF_TWO_PATH_LEGACY = InstanceIdentifier.builder(OUTER_LIST_PATH_LEGACY)
+            .node(TWO_QNAME).build();
+
+    static final QName ANY_XML_LEAF_QNAME = QName.create(TEST_QNAME, "leaf");;
+    static final QName ANY_XML_INNER_QNAME = QName.create(TEST_QNAME, "inner");
+    static final QName ANY_XML_INNER_LEAF_QNAME = QName.create(TEST_QNAME, "inner-leaf");
+
+    SchemaContext createTestContext() {
+        YangParserImpl parser = new YangParserImpl();
+        Set<Module> modules = parser.parseYangModelsFromStreams(Collections.singletonList(DataNormalizerTest.class
+                .getResourceAsStream("/normalization-test.yang")));
+        return parser.resolveSchemaContext(modules);
+    }
+
+    @Test
+    public void testToNormalizedInstanceIdentifier() {
+        SchemaContext testCtx = createTestContext();
+        DataNormalizer normalizer = new DataNormalizer(testCtx);
+
+        InstanceIdentifier normalizedPath = normalizer.toNormalized(LEAF_TWO_PATH_LEGACY);
+
+        verifyNormalizedInstanceIdentifier(normalizedPath, TEST_QNAME, OUTER_LIST_QNAME, new Object[] {
+                OUTER_LIST_QNAME, ID_QNAME, OUTER_LIST_ID }, OUTER_CHOICE_QNAME, TWO_QNAME);
+    }
+
+    private void verifyNormalizedInstanceIdentifier(InstanceIdentifier actual, Object... expPath) {
+
+        assertNotNull("Actual InstanceIdentifier is null", actual);
+        assertEquals("InstanceIdentifier path length", expPath.length, actual.getPath().size());
+
+        for (int i = 0; i < expPath.length; i++) {
+            PathArgument actualArg = actual.getPath().get(i);
+            if (expPath[i] instanceof Object[]) { // NodeIdentifierWithPredicates
+                Object[] exp = (Object[]) expPath[i];
+                assertEquals("Actual path arg " + (i + 1) + " class", NodeIdentifierWithPredicates.class,
+                        actualArg.getClass());
+                NodeIdentifierWithPredicates actualNode = (NodeIdentifierWithPredicates) actualArg;
+                assertEquals("Actual path arg " + (i + 1) + " node type", exp[0], actualNode.getNodeType());
+                assertEquals("Actual path arg " + (i + 1) + " key values map size", 1, actualNode.getKeyValues().size());
+                Entry<QName, Object> keyValuesEntry = actualNode.getKeyValues().entrySet().iterator().next();
+                assertEquals("Actual path arg " + (i + 1) + " key values map key", exp[1], keyValuesEntry.getKey());
+                assertEquals("Actual path arg " + (i + 1) + " key values map value", exp[2], keyValuesEntry.getValue());
+            } else if (expPath[i] instanceof Set) { // AugmentationIdentifier
+                assertEquals("Actual path arg " + (i + 1) + " class", AugmentationIdentifier.class,
+                        actualArg.getClass());
+                AugmentationIdentifier actualNode = (AugmentationIdentifier) actualArg;
+                assertEquals("Actual path arg " + (i + 1) + " PossibleChildNames", expPath[i],
+                        actualNode.getPossibleChildNames());
+            } else {
+                assertEquals("Actual path arg " + (i + 1) + " node type", expPath[i], actualArg.getNodeType());
+            }
+        }
+    }
+
+    @Test
+    public void testToLegacyInstanceIdentifier() throws DataNormalizationException {
+
+        DataNormalizer normalizer = new DataNormalizer(createTestContext());
+
+        InstanceIdentifier normalized = InstanceIdentifier.builder().node(TEST_QNAME).node(OUTER_LIST_QNAME)
+                .nodeWithKey(OUTER_LIST_QNAME, ID_QNAME, OUTER_LIST_ID).node(OUTER_CHOICE_QNAME).node(TWO_QNAME)
+                .build();
+
+        InstanceIdentifier legacy = normalizer.toLegacy(normalized);
+
+        assertEquals("Legacy InstanceIdentifier", LEAF_TWO_PATH_LEGACY, legacy);
+    }
+
+    @Test
+    public void testToLegacyNormalizedNode() {
+
+        ChoiceNode choiceNode1 = Builders.choiceBuilder().withNodeIdentifier(new NodeIdentifier(OUTER_CHOICE_QNAME))
+                .withChild(ImmutableNodes.leafNode(TWO_QNAME, "two"))
+                .withChild(ImmutableNodes.leafNode(THREE_QNAME, "three")).build();
+
+        MapEntryNode innerListEntryNode1 = Builders.mapEntryBuilder()
+                .withNodeIdentifier(new NodeIdentifierWithPredicates(INNER_LIST_QNAME, NAME_QNAME, "inner-name1"))
+                .withChild(ImmutableNodes.leafNode(NAME_QNAME, "inner-name1"))
+                .withChild(ImmutableNodes.leafNode(VALUE_QNAME, "inner-value1")).build();
+
+        MapEntryNode innerListEntryNode2 = Builders.mapEntryBuilder()
+                .withNodeIdentifier(new NodeIdentifierWithPredicates(INNER_LIST_QNAME, NAME_QNAME, "inner-name2"))
+                .withChild(ImmutableNodes.leafNode(NAME_QNAME, "inner-name2"))
+                .withChild(ImmutableNodes.leafNode(VALUE_QNAME, "inner-value2")).build();
+
+        OrderedMapNode innerListNode = Builders.orderedMapBuilder()
+                .withNodeIdentifier(new NodeIdentifier(INNER_LIST_QNAME)).withChild(innerListEntryNode1)
+                .withChild(innerListEntryNode2).build();
+
+        Short outerListID1 = Short.valueOf((short) 10);
+        MapEntryNode outerListEntryNode1 = Builders.mapEntryBuilder()
+                .withNodeIdentifier(new NodeIdentifierWithPredicates(OUTER_LIST_QNAME, ID_QNAME, outerListID1))
+                .withChild(ImmutableNodes.leafNode(ID_QNAME, outerListID1)).withChild(choiceNode1)
+                .withChild(innerListNode).build();
+
+        ChoiceNode choiceNode2 = Builders.choiceBuilder().withNodeIdentifier(new NodeIdentifier(OUTER_CHOICE_QNAME))
+                .withChild(ImmutableNodes.leafNode(ONE_QNAME, "one")).build();
+
+        Short outerListID2 = Short.valueOf((short) 20);
+        MapEntryNode outerListEntryNode2 = Builders.mapEntryBuilder()
+                .withNodeIdentifier(new NodeIdentifierWithPredicates(OUTER_LIST_QNAME, ID_QNAME, outerListID2))
+                .withChild(ImmutableNodes.leafNode(ID_QNAME, outerListID2)).withChild(choiceNode2).build();
+
+        MapNode outerListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(OUTER_LIST_QNAME))
+                .withChild(outerListEntryNode1).withChild(outerListEntryNode2).build();
+
+        UnkeyedListEntryNode unkeyedListEntryNode1 = Builders.unkeyedListEntryBuilder()
+                .withNodeIdentifier(new NodeIdentifier(UNKEYED_LIST_QNAME))
+                .withChild(ImmutableNodes.leafNode(NAME_QNAME, "unkeyed1")).build();
+
+        UnkeyedListEntryNode unkeyedListEntryNode2 = Builders.unkeyedListEntryBuilder()
+                .withNodeIdentifier(new NodeIdentifier(UNKEYED_LIST_QNAME))
+                .withChild(ImmutableNodes.leafNode(NAME_QNAME, "unkeyed2")).build();
+
+        UnkeyedListNode unkeyedListNode = Builders.unkeyedListBuilder()
+                .withNodeIdentifier(new NodeIdentifier(UNKEYED_LIST_QNAME)).withChild(unkeyedListEntryNode1)
+                .withChild(unkeyedListEntryNode2).build();
+
+        ContainerNode testContainerNode = Builders.containerBuilder()
+                .withNodeIdentifier(new NodeIdentifier(TEST_QNAME)).withChild(outerListNode).withChild(unkeyedListNode)
+                .build();
+
+        Node<?> legacyNode = DataNormalizer.toLegacy(testContainerNode);
+
+        verifyLegacyNode(
+                legacyNode,
+                expectCompositeNode(
+                        TEST_QNAME,
+                        expectCompositeNode(
+                                OUTER_LIST_QNAME,
+                                expectSimpleNode(ID_QNAME, outerListID1),
+                                expectSimpleNode(TWO_QNAME, "two"),
+                                expectSimpleNode(THREE_QNAME, "three"),
+
+                                expectCompositeNode(INNER_LIST_QNAME, expectSimpleNode(NAME_QNAME, "inner-name1"),
+                                        expectSimpleNode(VALUE_QNAME, "inner-value1")),
+
+                                expectCompositeNode(INNER_LIST_QNAME, expectSimpleNode(NAME_QNAME, "inner-name2"),
+                                        expectSimpleNode(VALUE_QNAME, "inner-value2"))),
+                        expectCompositeNode(OUTER_LIST_QNAME, expectSimpleNode(ID_QNAME, outerListID2),
+                                expectSimpleNode(ONE_QNAME, "one")),
+                        expectCompositeNode(UNKEYED_LIST_QNAME, expectSimpleNode(NAME_QNAME, "unkeyed1")),
+                        expectCompositeNode(UNKEYED_LIST_QNAME, expectSimpleNode(NAME_QNAME, "unkeyed2"))));
+
+        // Conversion of Mixin type nodes is not supported.
+
+        assertNull("Expected null returned for Mixin type node", DataNormalizer.toLegacy(outerListNode));
+    }
+
+    /**
+     * Following data are constructed: <any-xml-data> <inner>
+     * <inner-leaf>inner-leaf-value</inner-leaf> </inner>
+     * <leaf>leaf-value</leaf> <any-xml-data>
+     */
+    @Test
+    public void testToLegacyNormalizedNodeWithAnyXml() {
+
+        Node<?> innerLeafChild = NodeFactory.createImmutableSimpleNode(ANY_XML_INNER_LEAF_QNAME, null,
+                "inner-leaf-value");
+        CompositeNode innerContainer = NodeFactory.createImmutableCompositeNode(ANY_XML_INNER_QNAME, null,
+                Collections.<Node<?>> singletonList(innerLeafChild));
+
+        Node<?> leafChild = NodeFactory.createImmutableSimpleNode(ANY_XML_LEAF_QNAME, null, "leaf-value");
+        CompositeNode anyXmlNodeValue = NodeFactory.createImmutableCompositeNode(ANY_XML_DATA_QNAME, null,
+                Arrays.asList(leafChild, innerContainer));
+
+        AnyXmlNode testAnyXmlNode = Builders.anyXmlBuilder().withNodeIdentifier(new NodeIdentifier(TEST_QNAME))
+                .withValue(anyXmlNodeValue).build();
+
+        ContainerNode testContainerNode = Builders.containerBuilder()
+                .withNodeIdentifier(new NodeIdentifier(TEST_QNAME)).withChild(testAnyXmlNode).build();
+
+        DataNormalizer normalizer = new DataNormalizer(createTestContext());
+        Node<?> legacyNode = normalizer.toLegacy(InstanceIdentifier.builder(TEST_QNAME).build(), testContainerNode);
+
+        verifyLegacyNode(
+                legacyNode,
+                expectCompositeNode(
+                        TEST_QNAME,
+                        expectCompositeNode(
+                                ANY_XML_DATA_QNAME,
+                                expectSimpleNode(ANY_XML_LEAF_QNAME, "leaf-value"),
+                                expectCompositeNode(ANY_XML_INNER_QNAME,
+                                        expectSimpleNode(ANY_XML_INNER_LEAF_QNAME, "inner-leaf-value")))));
+    }
+
+    @Test
+    public void testToLegacyNormalizedNodeWithLeafLists() {
+
+        CompositeNodeBuilder<ImmutableCompositeNode> testBuilder = ImmutableCompositeNode.builder();
+        testBuilder.setQName(TEST_QNAME);
+
+        ListNodeBuilder<Object, LeafSetEntryNode<Object>> leafSetBuilder = Builders.leafSetBuilder()
+                .withNodeIdentifier(new NodeIdentifier(UNORDERED_LEAF_LIST_QNAME));
+        for (int i = 1; i <= 3; i++) {
+            leafSetBuilder.withChildValue("unordered-value" + i);
+        }
+
+        ListNodeBuilder<Object, LeafSetEntryNode<Object>> orderedLeafSetBuilder = Builders.orderedLeafSetBuilder()
+                .withNodeIdentifier(new NodeIdentifier(ORDERED_LEAF_LIST_QNAME));
+        for (int i = 3; i > 0; i--) {
+            orderedLeafSetBuilder.withChildValue("ordered-value" + i);
+        }
+
+        ContainerNode testContainerNode = Builders.containerBuilder()
+                .withNodeIdentifier(new NodeIdentifier(TEST_QNAME)).withChild(leafSetBuilder.build())
+                .withChild(orderedLeafSetBuilder.build()).build();
+
+        DataNormalizer normalizer = new DataNormalizer(createTestContext());
+
+        Node<?> legacyNode = normalizer.toLegacy(InstanceIdentifier.builder(TEST_QNAME).build(), testContainerNode);
+
+        verifyLegacyNode(
+                legacyNode,
+                expectCompositeNode(TEST_QNAME, expectSimpleNode(UNORDERED_LEAF_LIST_QNAME, "unordered-value1"),
+                        expectSimpleNode(UNORDERED_LEAF_LIST_QNAME, "unordered-value2"),
+                        expectSimpleNode(UNORDERED_LEAF_LIST_QNAME, "unordered-value3"),
+                        expectSimpleNode(ORDERED_LEAF_LIST_QNAME, "ordered-value3"),
+                        expectSimpleNode(ORDERED_LEAF_LIST_QNAME, "ordered-value2"),
+                        expectSimpleNode(ORDERED_LEAF_LIST_QNAME, "ordered-value1")));
+    }
+
+    @Test
+    public void testToLegacyNormalizedNodeWithAugmentation() {
+
+        AugmentationNode augmentationNode = Builders.augmentationBuilder()
+                .withNodeIdentifier(new AugmentationIdentifier(Sets.newHashSet(AUGMENTED_LEAF_QNAME)))
+                .withChild(ImmutableNodes.leafNode(AUGMENTED_LEAF_QNAME, "augmented-value")).build();
+
+        ContainerNode outerContainerNode = Builders.containerBuilder()
+                .withNodeIdentifier(new NodeIdentifier(OUTER_CONTAINER_QNAME)).withChild(augmentationNode).build();
+
+        ContainerNode testContainerNode = Builders.containerBuilder()
+                .withNodeIdentifier(new NodeIdentifier(TEST_QNAME)).withChild(outerContainerNode).build();
+
+        DataNormalizer normalizer = new DataNormalizer(createTestContext());
+
+        Node<?> legacyNode = normalizer.toLegacy(InstanceIdentifier.builder(TEST_QNAME).build(), testContainerNode);
+
+        verifyLegacyNode(
+                legacyNode,
+                expectCompositeNode(
+                        TEST_QNAME,
+                        expectCompositeNode(OUTER_CONTAINER_QNAME,
+                                expectSimpleNode(AUGMENTED_LEAF_QNAME, "augmented-value"))));
+    }
+
+    private boolean isOrdered(QName nodeName) {
+        return ORDERED_LEAF_LIST_QNAME.equals(nodeName) || INNER_LIST_QNAME.equals(nodeName);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void verifyLegacyNode(Node<?> actual, LegacyNodeData expNodeData) {
+
+        assertNotNull("Actual Node is null", actual);
+        assertTrue("Expected CompositeNode instance", actual instanceof CompositeNode);
+        CompositeNode actualCN = (CompositeNode) actual;
+        assertEquals("Node key", expNodeData.nodeKey, actualCN.getKey());
+
+        List<LegacyNodeData> expChildData = Lists.newArrayList();
+        List<LegacyNodeData> unorderdChildData = Lists.newArrayList();
+        for (LegacyNodeData data : (List<LegacyNodeData>) expNodeData.nodeData) {
+            if (isOrdered(data.nodeKey)) {
+                expChildData.add(data);
+            } else {
+                unorderdChildData.add(data);
+            }
+        }
+
+        Collections.sort(unorderdChildData, new Comparator<LegacyNodeData>() {
+            @Override
+            public int compare(LegacyNodeData arg1, LegacyNodeData arg2) {
+                String str1 = arg1.nodeKey.getLocalName();
+                if (!(arg1.nodeData instanceof List))
+                    str1 += arg1.nodeData; // add simple node value
+
+                String str2 = arg2.nodeKey.getLocalName();
+                if (!(arg2.nodeData instanceof List))
+                    str2 += arg2.nodeData; // add simple node value
+
+                return str1.compareTo(str2);
+            }
+        });
+
+        expChildData.addAll(unorderdChildData);
+
+        List<Node<?>> actualChildNodes = Lists.newArrayList();
+        List<Node<?>> unorderedChildNodes = Lists.newArrayList();
+        for (Node<?> node : actualCN.getValue()) {
+            if (isOrdered(node.getKey())) {
+                actualChildNodes.add(node);
+            } else {
+                unorderedChildNodes.add(node);
+            }
+        }
+
+        Collections.sort(unorderedChildNodes, new Comparator<Node<?>>() {
+            @Override
+            public int compare(Node<?> n1, Node<?> n2) {
+                String str1 = n1.getKey().getLocalName();
+                if (n1 instanceof SimpleNode)
+                    str1 += ((SimpleNode<?>) n1).getValue();
+
+                String str2 = n2.getKey().getLocalName();
+                if (n2 instanceof SimpleNode)
+                    str2 += ((SimpleNode<?>) n2).getValue();
+
+                return str1.compareTo(str2);
+            }
+        });
+
+        actualChildNodes.addAll(unorderedChildNodes);
+
+        for (Node<?> actualChild : actualChildNodes) {
+            LegacyNodeData expData = expChildData.isEmpty() ? null : expChildData.remove(0);
+            assertNotNull("Unexpected child node with key " + actualChild.getKey(), expData);
+            assertEquals("Child node QName", expData.nodeKey, actualChild.getKey());
+
+            if (expData.nodeData instanceof List) { // List represents a
+                                                    // composite node
+                verifyLegacyNode(actualChild, expData);
+            } else { // else a simple node
+                assertTrue("Expected SimpleNode instance", actualChild instanceof SimpleNode);
+                assertEquals("Child node value with key " + actualChild.getKey(), expData.nodeData,
+                        ((SimpleNode<?>) actualChild).getValue());
+            }
+        }
+
+        if (!expChildData.isEmpty()) {
+            fail("Missing child nodes: " + expChildData);
+        }
+    }
+
+    private LegacyNodeData expectCompositeNode(QName key, LegacyNodeData... childData) {
+        return new LegacyNodeData(key, Lists.newArrayList(childData));
+    }
+
+    private LegacyNodeData expectSimpleNode(QName key, Object value) {
+        return new LegacyNodeData(key, value);
+    }
+
+    @Test
+    public void testToNormalizedCompositeNode() {
+        SchemaContext testCtx = createTestContext();
+        DataNormalizer normalizer = new DataNormalizer(testCtx);
+
+        CompositeNodeBuilder<ImmutableCompositeNode> testBuilder = ImmutableCompositeNode.builder();
+        testBuilder.setQName(TEST_QNAME);
+
+        CompositeNodeBuilder<ImmutableCompositeNode> outerListBuilder = ImmutableCompositeNode.builder();
+        outerListBuilder.setQName(OUTER_LIST_QNAME);
+        outerListBuilder.addLeaf(ID_QNAME, 10);
+        outerListBuilder.addLeaf(ONE_QNAME, "one");
+
+        for (int i = 3; i > 0; i--) {
+            CompositeNodeBuilder<ImmutableCompositeNode> innerListBuilder = ImmutableCompositeNode.builder();
+            innerListBuilder.setQName(INNER_LIST_QNAME);
+            innerListBuilder.addLeaf(NAME_QNAME, "inner-name" + i);
+            innerListBuilder.addLeaf(VALUE_QNAME, "inner-value" + i);
+            outerListBuilder.add(innerListBuilder.toInstance());
+        }
+
+        testBuilder.add(outerListBuilder.toInstance());
+
+        outerListBuilder = ImmutableCompositeNode.builder();
+        outerListBuilder.setQName(OUTER_LIST_QNAME);
+        outerListBuilder.addLeaf(ID_QNAME, 20);
+        outerListBuilder.addLeaf(TWO_QNAME, "two");
+        outerListBuilder.addLeaf(THREE_QNAME, "three");
+        testBuilder.add(outerListBuilder.toInstance());
+
+        for (int i = 1; i <= 2; i++) {
+            CompositeNodeBuilder<ImmutableCompositeNode> unkeyedListBuilder = ImmutableCompositeNode.builder();
+            unkeyedListBuilder.setQName(UNKEYED_LIST_QNAME);
+            unkeyedListBuilder.addLeaf(NAME_QNAME, "unkeyed-name" + i);
+            testBuilder.add(unkeyedListBuilder.toInstance());
+        }
+
+        Entry<InstanceIdentifier, NormalizedNode<?, ?>> normalizedNodeEntry = normalizer
+                .toNormalized(new AbstractMap.SimpleEntry<InstanceIdentifier, CompositeNode>(new InstanceIdentifier(
+                        ImmutableList.<PathArgument> of(new NodeIdentifier(TEST_QNAME))), testBuilder.toInstance()));
+
+        verifyNormalizedInstanceIdentifier(normalizedNodeEntry.getKey(), TEST_QNAME);
+
+        verifyNormalizedNode(
+                normalizedNodeEntry.getValue(),
+                expectContainerNode(
+                        TEST_QNAME,
+                        expectMapNode(
+                                OUTER_LIST_QNAME,
+                                expectMapEntryNode(
+                                        OUTER_LIST_QNAME,
+                                        ID_QNAME,
+                                        10,
+                                        expectLeafNode(ID_QNAME, 10),
+                                        expectChoiceNode(OUTER_CHOICE_QNAME, expectLeafNode(ONE_QNAME, "one")),
+                                        expectOrderedMapNode(
+                                                INNER_LIST_QNAME,
+                                                expectMapEntryNode(INNER_LIST_QNAME, NAME_QNAME, "inner-name3",
+                                                        expectLeafNode(NAME_QNAME, "inner-name3"),
+                                                        expectLeafNode(VALUE_QNAME, "inner-value3")),
+                                                expectMapEntryNode(INNER_LIST_QNAME, NAME_QNAME, "inner-name2",
+                                                        expectLeafNode(NAME_QNAME, "inner-name2"),
+                                                        expectLeafNode(VALUE_QNAME, "inner-value2")),
+                                                expectMapEntryNode(INNER_LIST_QNAME, NAME_QNAME, "inner-name1",
+                                                        expectLeafNode(NAME_QNAME, "inner-name1"),
+                                                        expectLeafNode(VALUE_QNAME, "inner-value1")))),
+                                expectMapEntryNode(
+                                        OUTER_LIST_QNAME,
+                                        ID_QNAME,
+                                        20,
+                                        expectLeafNode(ID_QNAME, 20),
+                                        expectChoiceNode(OUTER_CHOICE_QNAME, expectLeafNode(TWO_QNAME, "two"),
+                                                expectLeafNode(THREE_QNAME, "three")))),
+                        expectUnkeyedListNode(
+                                UNKEYED_LIST_QNAME,
+                                expectUnkeyedListEntryNode(UNKEYED_LIST_QNAME,
+                                        expectLeafNode(NAME_QNAME, "unkeyed-name1")),
+                                expectUnkeyedListEntryNode(UNKEYED_LIST_QNAME,
+                                        expectLeafNode(NAME_QNAME, "unkeyed-name2")))));
+    }
+
+    @Test
+    public void testToNormalizedCompositeNodeWithAnyXml() {
+        SchemaContext testCtx = createTestContext();
+        DataNormalizer normalizer = new DataNormalizer(testCtx);
+
+        CompositeNodeBuilder<ImmutableCompositeNode> testBuilder = ImmutableCompositeNode.builder();
+        testBuilder.setQName(TEST_QNAME);
+
+        CompositeNodeBuilder<ImmutableCompositeNode> anyXmlBuilder = ImmutableCompositeNode.builder();
+        anyXmlBuilder.setQName(ANY_XML_DATA_QNAME);
+        anyXmlBuilder.addLeaf(ANY_XML_LEAF_QNAME, "leaf-value");
+
+        CompositeNodeBuilder<ImmutableCompositeNode> innerBuilder = ImmutableCompositeNode.builder();
+        innerBuilder.setQName(ANY_XML_INNER_QNAME);
+        innerBuilder.addLeaf(ANY_XML_INNER_LEAF_QNAME, "inner-leaf-value");
+
+        anyXmlBuilder.add(innerBuilder.toInstance());
+        CompositeNode anyXmlLegacy = anyXmlBuilder.toInstance();
+        testBuilder.add(anyXmlLegacy);
+
+        Entry<InstanceIdentifier, NormalizedNode<?, ?>> normalizedNodeEntry = normalizer
+                .toNormalized(new AbstractMap.SimpleEntry<InstanceIdentifier, CompositeNode>(new InstanceIdentifier(
+                        ImmutableList.<PathArgument> of(new NodeIdentifier(TEST_QNAME))), testBuilder.toInstance()));
+
+        verifyNormalizedInstanceIdentifier(normalizedNodeEntry.getKey(), TEST_QNAME);
+
+        verifyNormalizedNode(normalizedNodeEntry.getValue(),
+                expectContainerNode(TEST_QNAME, expectAnyXmlNode(ANY_XML_DATA_QNAME, anyXmlLegacy)));
+    }
+
+    @Test
+    public void testToNormalizedCompositeNodeWithAugmentation() {
+        SchemaContext testCtx = createTestContext();
+        DataNormalizer normalizer = new DataNormalizer(testCtx);
+
+        CompositeNodeBuilder<ImmutableCompositeNode> testBuilder = ImmutableCompositeNode.builder();
+        testBuilder.setQName(TEST_QNAME);
+
+        CompositeNodeBuilder<ImmutableCompositeNode> outerContBuilder = ImmutableCompositeNode.builder();
+        outerContBuilder.setQName(OUTER_CONTAINER_QNAME);
+        outerContBuilder.addLeaf(AUGMENTED_LEAF_QNAME, "augmented-value");
+
+        testBuilder.add(outerContBuilder.toInstance());
+
+        Entry<InstanceIdentifier, NormalizedNode<?, ?>> normalizedNodeEntry = normalizer
+                .toNormalized(new AbstractMap.SimpleEntry<InstanceIdentifier, CompositeNode>(new InstanceIdentifier(
+                        ImmutableList.<PathArgument> of(new NodeIdentifier(TEST_QNAME))), testBuilder.toInstance()));
+
+        verifyNormalizedInstanceIdentifier(normalizedNodeEntry.getKey(), TEST_QNAME);
+
+        NormalizedNodeData expAugmentation = expectAugmentation(AUGMENTED_LEAF_QNAME,
+                expectLeafNode(AUGMENTED_LEAF_QNAME, "augmented-value"));
+
+        verifyNormalizedNode(normalizedNodeEntry.getValue(),
+                expectContainerNode(TEST_QNAME, expectContainerNode(OUTER_CONTAINER_QNAME, expAugmentation)));
+
+        normalizedNodeEntry = normalizer.toNormalized(new AbstractMap.SimpleEntry<InstanceIdentifier, CompositeNode>(
+                new InstanceIdentifier(Lists.newArrayList(new NodeIdentifier(TEST_QNAME), new NodeIdentifier(
+                        OUTER_CONTAINER_QNAME))), outerContBuilder.toInstance()));
+
+        verifyNormalizedInstanceIdentifier(normalizedNodeEntry.getKey(), TEST_QNAME, OUTER_CONTAINER_QNAME,
+                Sets.newHashSet(AUGMENTED_LEAF_QNAME));
+
+        verifyNormalizedNode(normalizedNodeEntry.getValue(), expAugmentation);
+    }
+
+    @Test
+    public void testToNormalizedCompositeNodeWithLeafLists() {
+        SchemaContext testCtx = createTestContext();
+        DataNormalizer normalizer = new DataNormalizer(testCtx);
+
+        CompositeNodeBuilder<ImmutableCompositeNode> testBuilder = ImmutableCompositeNode.builder();
+        testBuilder.setQName(TEST_QNAME);
+
+        for (int i = 1; i <= 3; i++) {
+            testBuilder.addLeaf(UNORDERED_LEAF_LIST_QNAME, "unordered-value" + i);
+        }
+
+        for (int i = 3; i > 0; i--) {
+            testBuilder.addLeaf(ORDERED_LEAF_LIST_QNAME, "ordered-value" + i);
+        }
+
+        Entry<InstanceIdentifier, NormalizedNode<?, ?>> normalizedNodeEntry = normalizer
+                .toNormalized(new AbstractMap.SimpleEntry<InstanceIdentifier, CompositeNode>(new InstanceIdentifier(
+                        ImmutableList.<PathArgument> of(new NodeIdentifier(TEST_QNAME))), testBuilder.toInstance()));
+
+        verifyNormalizedInstanceIdentifier(normalizedNodeEntry.getKey(), TEST_QNAME);
+
+        verifyNormalizedNode(
+                normalizedNodeEntry.getValue(),
+                expectContainerNode(
+                        TEST_QNAME,
+                        expectLeafSetNode(UNORDERED_LEAF_LIST_QNAME,
+                                expectLeafSetEntryNode(UNORDERED_LEAF_LIST_QNAME, "unordered-value1"),
+                                expectLeafSetEntryNode(UNORDERED_LEAF_LIST_QNAME, "unordered-value2"),
+                                expectLeafSetEntryNode(UNORDERED_LEAF_LIST_QNAME, "unordered-value3")),
+                        expectOrderedLeafSetNode(ORDERED_LEAF_LIST_QNAME,
+                                expectLeafSetEntryNode(ORDERED_LEAF_LIST_QNAME, "ordered-value3"),
+                                expectLeafSetEntryNode(ORDERED_LEAF_LIST_QNAME, "ordered-value2"),
+                                expectLeafSetEntryNode(ORDERED_LEAF_LIST_QNAME, "ordered-value1"))));
+    }
+
+    @SuppressWarnings("unchecked")
+    private void verifyNormalizedNode(NormalizedNode<?, ?> actual, NormalizedNodeData expNodeData) {
+
+        Class<?> expNodeClass = expNodeData.nodeClass;
+        PathArgument expNodeID = expNodeData.nodeID;
+
+        assertNotNull("Actual NormalizedNode is null", actual);
+        assertTrue("NormalizedNode instance " + actual.getClass() + " is not derived from " + expNodeClass,
+                expNodeClass.isAssignableFrom(actual.getClass()));
+        assertEquals("NormalizedNode identifier", expNodeID, actual.getIdentifier());
+
+        if (expNodeData.nodeData instanceof List) {
+            Map<PathArgument, Integer> orderingMap = null;
+            if (expNodeClass.equals(OrderedMapNode.class) || expNodeClass.equals(OrderedLeafSetNode.class)) {
+                orderingMap = Maps.newHashMap();
+            }
+
+            int i = 1;
+            Map<PathArgument, NormalizedNodeData> expChildDataMap = Maps.newHashMap();
+            List<NormalizedNodeData> expChildDataList = (List<NormalizedNodeData>) expNodeData.nodeData;
+            for (NormalizedNodeData data : expChildDataList) {
+                expChildDataMap.put(data.nodeID, data);
+
+                if (orderingMap != null) {
+                    orderingMap.put(data.nodeID, i++);
+                }
+            }
+
+            assertNotNull("Actual value is null for node " + actual.getIdentifier(), actual.getValue());
+            assertTrue("Expected value instance Iterable for node " + actual.getIdentifier(),
+                    Iterable.class.isAssignableFrom(actual.getValue().getClass()));
+
+            i = 1;
+            for (NormalizedNode<?, ?> actualChild : (Iterable<NormalizedNode<?, ?>>) actual.getValue()) {
+                NormalizedNodeData expChildData = expNodeClass.equals(UnkeyedListNode.class) ? expChildDataList
+                        .remove(0) : expChildDataMap.remove(actualChild.getIdentifier());
+
+                assertNotNull(
+                        "Unexpected child node " + actualChild.getClass() + " with identifier "
+                                + actualChild.getIdentifier() + " for parent node " + actual.getClass()
+                                + " with identifier " + actual.getIdentifier(), expChildData);
+
+                if (orderingMap != null) {
+                    assertEquals("Order index for child node " + actualChild.getIdentifier(),
+                            orderingMap.get(actualChild.getIdentifier()), Integer.valueOf(i));
+                }
+
+                verifyNormalizedNode(actualChild, expChildData);
+                i++;
+            }
+
+            if (expNodeClass.equals(UnkeyedListNode.class)) {
+                if (expChildDataList.size() > 0) {
+                    fail("Missing " + expChildDataList.size() + " child nodes for parent " + actual.getIdentifier());
+                }
+            } else {
+                if (!expChildDataMap.isEmpty()) {
+                    fail("Missing child nodes for parent " + actual.getIdentifier() + ": " + expChildDataMap.keySet());
+                }
+            }
+        } else {
+            assertEquals("Leaf value for node " + actual.getIdentifier(), expNodeData.nodeData, actual.getValue());
+        }
+    }
+
+    private NormalizedNodeData expectOrderedLeafSetNode(QName nodeName, NormalizedNodeData... childData) {
+        return new NormalizedNodeData(new NodeIdentifier(nodeName), OrderedLeafSetNode.class,
+                Lists.newArrayList(childData));
+    }
+
+    private NormalizedNodeData expectLeafSetNode(QName nodeName, NormalizedNodeData... childData) {
+        return new NormalizedNodeData(new NodeIdentifier(nodeName), LeafSetNode.class, Lists.newArrayList(childData));
+    }
+
+    private NormalizedNodeData expectLeafSetEntryNode(QName nodeName, Object value) {
+        return new NormalizedNodeData(new NodeWithValue(nodeName, value), LeafSetEntryNode.class, value);
+    }
+
+    private NormalizedNodeData expectUnkeyedListNode(QName nodeName, NormalizedNodeData... childData) {
+        return new NormalizedNodeData(new NodeIdentifier(nodeName), UnkeyedListNode.class,
+                Lists.newArrayList(childData));
+    }
+
+    private NormalizedNodeData expectUnkeyedListEntryNode(QName nodeName, NormalizedNodeData... childData) {
+        return new NormalizedNodeData(new NodeIdentifier(nodeName), UnkeyedListEntryNode.class,
+                Lists.newArrayList(childData));
+    }
+
+    private NormalizedNodeData expectAugmentation(QName augmentedNodeName, NormalizedNodeData... childData) {
+        return new NormalizedNodeData(new AugmentationIdentifier(Sets.newHashSet(augmentedNodeName)),
+                AugmentationNode.class, Lists.newArrayList(childData));
+    }
+
+    private NormalizedNodeData expectAnyXmlNode(QName nodeName, Object value) {
+        return new NormalizedNodeData(new NodeIdentifier(nodeName), AnyXmlNode.class, value);
+    }
+
+    private NormalizedNodeData expectContainerNode(QName nodeName, NormalizedNodeData... childData) {
+        return new NormalizedNodeData(new NodeIdentifier(nodeName), ContainerNode.class, Lists.newArrayList(childData));
+    }
+
+    private NormalizedNodeData expectChoiceNode(QName nodeName, NormalizedNodeData... childData) {
+        return new NormalizedNodeData(new NodeIdentifier(nodeName), ChoiceNode.class, Lists.newArrayList(childData));
+    }
+
+    private NormalizedNodeData expectLeafNode(QName nodeName, Object value) {
+        return new NormalizedNodeData(new NodeIdentifier(nodeName), LeafNode.class, value);
+
+    }
+
+    private NormalizedNodeData expectMapEntryNode(QName nodeName, QName key, Object value,
+            NormalizedNodeData... childData) {
+        return new NormalizedNodeData(new NodeIdentifierWithPredicates(nodeName, key, value), MapEntryNode.class,
+                Lists.newArrayList(childData));
+    }
+
+    private NormalizedNodeData expectMapNode(QName key, NormalizedNodeData... childData) {
+        return new NormalizedNodeData(new NodeIdentifier(key), MapNode.class, Lists.newArrayList(childData));
+    }
+
+    private NormalizedNodeData expectOrderedMapNode(QName key, NormalizedNodeData... childData) {
+        return new NormalizedNodeData(new NodeIdentifier(key), OrderedMapNode.class, Lists.newArrayList(childData));
+    }
+}
diff --git a/opendaylight/md-sal/sal-common-impl/src/test/resources/normalization-test.yang b/opendaylight/md-sal/sal-common-impl/src/test/resources/normalization-test.yang
new file mode 100644 (file)
index 0000000..6df5306
--- /dev/null
@@ -0,0 +1,74 @@
+module normalization-test {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:normalization:test";
+    prefix "norm-test";
+
+    revision "2014-03-13" {
+        description "Initial revision.";
+    }
+
+    grouping outer-grouping {
+    }
+
+    container test {
+        list outer-list {
+            key id;
+            leaf id {
+                type uint16;
+            }
+            choice outer-choice {
+                case one {
+                    leaf one {
+                        type string;
+                    }
+                }
+                case two-three {
+                    leaf two {
+                        type string;
+                    }
+                    leaf three {
+                        type string;
+                    }
+               }
+           }
+           list inner-list {
+                key name;
+                ordered-by user;
+
+                leaf name {
+                    type string;
+                }
+                leaf value {
+                    type string;
+                }
+            }
+        }
+
+        list unkeyed-list {
+            leaf name {
+                type string;
+            }
+        }
+
+        leaf-list unordered-leaf-list {
+            type string;
+        }
+
+        leaf-list ordered-leaf-list {
+            ordered-by user;
+            type string;
+        }
+
+        container outer-container {
+        }
+
+        anyxml any-xml-data;
+    }
+
+    augment /norm-test:test/norm-test:outer-container {
+
+        leaf augmented-leaf {
+           type string;
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/broker/impl/DataNormalizerTest.java b/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/broker/impl/DataNormalizerTest.java
deleted file mode 100644 (file)
index ac7b87a..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-package org.opendaylight.controller.md.sal.dom.broker.impl;
-
-import static org.junit.Assert.assertNotNull;
-
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
-import org.opendaylight.controller.md.sal.dom.store.impl.TestModel;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-public class DataNormalizerTest {
-
-    private static final Short OUTER_LIST_ID = (short)10;
-
-    private static final InstanceIdentifier OUTER_LIST_PATH_LEGACY = InstanceIdentifier.builder(TestModel.TEST_QNAME)
-            .nodeWithKey(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME,OUTER_LIST_ID).build();
-
-    private  static final InstanceIdentifier LEAF_TWO_PATH_LEGACY = InstanceIdentifier.builder(OUTER_LIST_PATH_LEGACY)
-            .node(TestModel.TWO_QNAME).build();
-
-    private static final ChoiceNode OUTER_CHOICE_ITEM = Builders.choiceBuilder()
-            .withNodeIdentifier(new NodeIdentifier(TestModel.OUTER_CHOICE_QNAME))
-            .withChild(ImmutableNodes.leafNode(TestModel.TWO_QNAME, "two"))
-            .withChild(ImmutableNodes.leafNode(TestModel.THREE_QNAME, "three"))
-            .build();
-
-    private static final MapEntryNode OUTER_LIST_WITHOUT_CHOICE = Builders.mapEntryBuilder()
-            .withNodeIdentifier(new NodeIdentifierWithPredicates(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME,OUTER_LIST_ID))
-            .withChild(ImmutableNodes.leafNode(TestModel.ID_QNAME, OUTER_LIST_ID))
-            .build();
-
-    private static final MapEntryNode OUTER_LIST_WITH_CHOICE = Builders.mapEntryBuilder()
-            .withNodeIdentifier(new NodeIdentifierWithPredicates(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME,OUTER_LIST_ID))
-            .withChild(ImmutableNodes.leafNode(TestModel.ID_QNAME, OUTER_LIST_ID))
-            .withChild(OUTER_CHOICE_ITEM)
-            .build();
-
-    @Test
-    public void test() {
-        SchemaContext testCtx = TestModel.createTestContext();
-        DataNormalizer normalizer = new DataNormalizer(testCtx);
-
-        InstanceIdentifier normalizedPath = normalizer.toNormalized(LEAF_TWO_PATH_LEGACY);
-
-        Node<?> outerListLegacy = DataNormalizer.toLegacy(OUTER_LIST_WITH_CHOICE);
-        assertNotNull(outerListLegacy);
-    }
-
-}