2 * Copyright (c) 2014 Brocade Communications Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.md.sal.common.impl.util.compat;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertNull;
13 import static org.junit.Assert.assertTrue;
14 import static org.junit.Assert.fail;
16 import com.google.common.collect.ImmutableList;
17 import com.google.common.collect.Iterables;
18 import com.google.common.collect.Lists;
19 import com.google.common.collect.Maps;
20 import com.google.common.collect.Sets;
22 import java.util.AbstractMap;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.Collections;
26 import java.util.Comparator;
27 import java.util.List;
29 import java.util.Map.Entry;
32 import org.junit.Test;
33 import org.opendaylight.yangtools.yang.common.QName;
34 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
35 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
36 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
37 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
38 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
39 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
40 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
41 import org.opendaylight.yangtools.yang.data.api.Node;
42 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
43 import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
44 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
45 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
46 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
47 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
48 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
49 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
50 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
51 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
52 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
53 import org.opendaylight.yangtools.yang.data.api.schema.OrderedLeafSetNode;
54 import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
55 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
56 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
57 import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
58 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
59 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
60 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
61 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
62 import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
63 import org.opendaylight.yangtools.yang.model.api.Module;
64 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
65 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
68 public class DataNormalizerTest {
70 static class NormalizedNodeData {
73 Object nodeData; // List for a container, value Object for a leaf
75 NormalizedNodeData(final PathArgument nodeID, final Class<?> nodeClass, final Object nodeData) {
77 this.nodeClass = nodeClass;
78 this.nodeData = nodeData;
82 static class LegacyNodeData {
84 Object nodeData; // List for a CompositeNode, value Object for a
87 LegacyNodeData(final QName nodeKey, final Object nodeData) {
88 this.nodeKey = nodeKey;
89 this.nodeData = nodeData;
93 public String toString() {
94 return nodeKey.toString();
98 static final QName TEST_QNAME = QName.create(
99 "urn:opendaylight:params:xml:ns:yang:controller:md:sal:normalization:test", "2014-03-13", "test");
100 static final QName OUTER_LIST_QNAME = QName.create(TEST_QNAME, "outer-list");
101 static final QName INNER_LIST_QNAME = QName.create(TEST_QNAME, "inner-list");
102 static final QName OUTER_CHOICE_QNAME = QName.create(TEST_QNAME, "outer-choice");
103 static final QName ID_QNAME = QName.create(TEST_QNAME, "id");
104 static final QName NAME_QNAME = QName.create(TEST_QNAME, "name");
105 static final QName VALUE_QNAME = QName.create(TEST_QNAME, "value");
107 static final YangInstanceIdentifier TEST_PATH = YangInstanceIdentifier.of(TEST_QNAME);
108 static final YangInstanceIdentifier OUTER_LIST_PATH = YangInstanceIdentifier.builder(TEST_PATH).node(OUTER_LIST_QNAME)
110 static final QName ONE_QNAME = QName.create(TEST_QNAME, "one");
111 static final QName TWO_QNAME = QName.create(TEST_QNAME, "two");
112 static final QName THREE_QNAME = QName.create(TEST_QNAME, "three");
114 static final QName ANY_XML_DATA_QNAME = QName.create(TEST_QNAME, "any-xml-data");
115 static final QName OUTER_CONTAINER_QNAME = QName.create(TEST_QNAME, "outer-container");
116 static final QName AUGMENTED_LEAF_QNAME = QName.create(TEST_QNAME, "augmented-leaf");
117 static final QName UNKEYED_LIST_QNAME = QName.create(TEST_QNAME, "unkeyed-list");
118 static final QName UNORDERED_LEAF_LIST_QNAME = QName.create(TEST_QNAME, "unordered-leaf-list");
119 static final QName ORDERED_LEAF_LIST_QNAME = QName.create(TEST_QNAME, "ordered-leaf-list");
121 static final Short OUTER_LIST_ID = (short) 10;
123 static final YangInstanceIdentifier OUTER_LIST_PATH_LEGACY = YangInstanceIdentifier.builder(TEST_PATH)
124 .nodeWithKey(OUTER_LIST_QNAME, ID_QNAME, OUTER_LIST_ID).build();
126 static final YangInstanceIdentifier LEAF_TWO_PATH_LEGACY = YangInstanceIdentifier.builder(OUTER_LIST_PATH_LEGACY)
127 .node(TWO_QNAME).build();
129 static final QName ANY_XML_LEAF_QNAME = QName.create(TEST_QNAME, "leaf");;
130 static final QName ANY_XML_INNER_QNAME = QName.create(TEST_QNAME, "inner");
131 static final QName ANY_XML_INNER_LEAF_QNAME = QName.create(TEST_QNAME, "inner-leaf");
133 SchemaContext createTestContext() {
134 YangParserImpl parser = new YangParserImpl();
135 Set<Module> modules = parser.parseYangModelsFromStreams(Collections.singletonList(DataNormalizerTest.class
136 .getResourceAsStream("/normalization-test.yang")));
137 return parser.resolveSchemaContext(modules);
141 public void testToNormalizedInstanceIdentifier() {
142 SchemaContext testCtx = createTestContext();
143 DataNormalizer normalizer = new DataNormalizer(testCtx);
145 YangInstanceIdentifier normalizedPath = normalizer.toNormalized(LEAF_TWO_PATH_LEGACY);
147 verifyNormalizedInstanceIdentifier(normalizedPath, TEST_QNAME, OUTER_LIST_QNAME, new Object[] {
148 OUTER_LIST_QNAME, ID_QNAME, OUTER_LIST_ID }, OUTER_CHOICE_QNAME, TWO_QNAME);
151 private void verifyNormalizedInstanceIdentifier(final YangInstanceIdentifier actual, final Object... expPath) {
153 assertNotNull("Actual InstanceIdentifier is null", actual);
154 assertEquals("InstanceIdentifier path length", expPath.length, Iterables.size(actual.getPathArguments()));
156 for (int i = 0; i < expPath.length; i++) {
157 PathArgument actualArg = Iterables.get(actual.getPathArguments(), i);
158 if (expPath[i] instanceof Object[]) { // NodeIdentifierWithPredicates
159 Object[] exp = (Object[]) expPath[i];
160 assertEquals("Actual path arg " + (i + 1) + " class", NodeIdentifierWithPredicates.class,
161 actualArg.getClass());
162 NodeIdentifierWithPredicates actualNode = (NodeIdentifierWithPredicates) actualArg;
163 assertEquals("Actual path arg " + (i + 1) + " node type", exp[0], actualNode.getNodeType());
164 assertEquals("Actual path arg " + (i + 1) + " key values map size", 1, actualNode.getKeyValues().size());
165 Entry<QName, Object> keyValuesEntry = actualNode.getKeyValues().entrySet().iterator().next();
166 assertEquals("Actual path arg " + (i + 1) + " key values map key", exp[1], keyValuesEntry.getKey());
167 assertEquals("Actual path arg " + (i + 1) + " key values map value", exp[2], keyValuesEntry.getValue());
168 } else if (expPath[i] instanceof Set) { // AugmentationIdentifier
169 assertEquals("Actual path arg " + (i + 1) + " class", AugmentationIdentifier.class,
170 actualArg.getClass());
171 AugmentationIdentifier actualNode = (AugmentationIdentifier) actualArg;
172 assertEquals("Actual path arg " + (i + 1) + " PossibleChildNames", expPath[i],
173 actualNode.getPossibleChildNames());
175 assertEquals("Actual path arg " + (i + 1) + " node type", expPath[i], actualArg.getNodeType());
181 public void testToLegacyInstanceIdentifier() throws DataNormalizationException {
183 DataNormalizer normalizer = new DataNormalizer(createTestContext());
185 YangInstanceIdentifier normalized = YangInstanceIdentifier.builder().node(TEST_QNAME).node(OUTER_LIST_QNAME)
186 .nodeWithKey(OUTER_LIST_QNAME, ID_QNAME, OUTER_LIST_ID).node(OUTER_CHOICE_QNAME).node(TWO_QNAME)
189 YangInstanceIdentifier legacy = normalizer.toLegacy(normalized);
191 assertEquals("Legacy InstanceIdentifier", LEAF_TWO_PATH_LEGACY, legacy);
195 public void testToLegacyNormalizedNode() {
197 ChoiceNode choiceNode1 = Builders.choiceBuilder().withNodeIdentifier(new NodeIdentifier(OUTER_CHOICE_QNAME))
198 .withChild(ImmutableNodes.leafNode(TWO_QNAME, "two"))
199 .withChild(ImmutableNodes.leafNode(THREE_QNAME, "three")).build();
201 MapEntryNode innerListEntryNode1 = Builders.mapEntryBuilder()
202 .withNodeIdentifier(new NodeIdentifierWithPredicates(INNER_LIST_QNAME, NAME_QNAME, "inner-name1"))
203 .withChild(ImmutableNodes.leafNode(NAME_QNAME, "inner-name1"))
204 .withChild(ImmutableNodes.leafNode(VALUE_QNAME, "inner-value1")).build();
206 MapEntryNode innerListEntryNode2 = Builders.mapEntryBuilder()
207 .withNodeIdentifier(new NodeIdentifierWithPredicates(INNER_LIST_QNAME, NAME_QNAME, "inner-name2"))
208 .withChild(ImmutableNodes.leafNode(NAME_QNAME, "inner-name2"))
209 .withChild(ImmutableNodes.leafNode(VALUE_QNAME, "inner-value2")).build();
211 OrderedMapNode innerListNode = Builders.orderedMapBuilder()
212 .withNodeIdentifier(new NodeIdentifier(INNER_LIST_QNAME)).withChild(innerListEntryNode1)
213 .withChild(innerListEntryNode2).build();
215 Short outerListID1 = Short.valueOf((short) 10);
216 MapEntryNode outerListEntryNode1 = Builders.mapEntryBuilder()
217 .withNodeIdentifier(new NodeIdentifierWithPredicates(OUTER_LIST_QNAME, ID_QNAME, outerListID1))
218 .withChild(ImmutableNodes.leafNode(ID_QNAME, outerListID1)).withChild(choiceNode1)
219 .withChild(innerListNode).build();
221 ChoiceNode choiceNode2 = Builders.choiceBuilder().withNodeIdentifier(new NodeIdentifier(OUTER_CHOICE_QNAME))
222 .withChild(ImmutableNodes.leafNode(ONE_QNAME, "one")).build();
224 Short outerListID2 = Short.valueOf((short) 20);
225 MapEntryNode outerListEntryNode2 = Builders.mapEntryBuilder()
226 .withNodeIdentifier(new NodeIdentifierWithPredicates(OUTER_LIST_QNAME, ID_QNAME, outerListID2))
227 .withChild(ImmutableNodes.leafNode(ID_QNAME, outerListID2)).withChild(choiceNode2).build();
229 MapNode outerListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(OUTER_LIST_QNAME))
230 .withChild(outerListEntryNode1).withChild(outerListEntryNode2).build();
232 UnkeyedListEntryNode unkeyedListEntryNode1 = Builders.unkeyedListEntryBuilder()
233 .withNodeIdentifier(new NodeIdentifier(UNKEYED_LIST_QNAME))
234 .withChild(ImmutableNodes.leafNode(NAME_QNAME, "unkeyed1")).build();
236 UnkeyedListEntryNode unkeyedListEntryNode2 = Builders.unkeyedListEntryBuilder()
237 .withNodeIdentifier(new NodeIdentifier(UNKEYED_LIST_QNAME))
238 .withChild(ImmutableNodes.leafNode(NAME_QNAME, "unkeyed2")).build();
240 UnkeyedListNode unkeyedListNode = Builders.unkeyedListBuilder()
241 .withNodeIdentifier(new NodeIdentifier(UNKEYED_LIST_QNAME)).withChild(unkeyedListEntryNode1)
242 .withChild(unkeyedListEntryNode2).build();
244 ContainerNode testContainerNode = Builders.containerBuilder()
245 .withNodeIdentifier(new NodeIdentifier(TEST_QNAME)).withChild(outerListNode).withChild(unkeyedListNode)
248 Node<?> legacyNode = DataNormalizer.toLegacy(testContainerNode);
256 expectSimpleNode(ID_QNAME, outerListID1),
257 expectSimpleNode(TWO_QNAME, "two"),
258 expectSimpleNode(THREE_QNAME, "three"),
260 expectCompositeNode(INNER_LIST_QNAME, expectSimpleNode(NAME_QNAME, "inner-name1"),
261 expectSimpleNode(VALUE_QNAME, "inner-value1")),
263 expectCompositeNode(INNER_LIST_QNAME, expectSimpleNode(NAME_QNAME, "inner-name2"),
264 expectSimpleNode(VALUE_QNAME, "inner-value2"))),
265 expectCompositeNode(OUTER_LIST_QNAME, expectSimpleNode(ID_QNAME, outerListID2),
266 expectSimpleNode(ONE_QNAME, "one")),
267 expectCompositeNode(UNKEYED_LIST_QNAME, expectSimpleNode(NAME_QNAME, "unkeyed1")),
268 expectCompositeNode(UNKEYED_LIST_QNAME, expectSimpleNode(NAME_QNAME, "unkeyed2"))));
270 // Conversion of Mixin type nodes is not supported.
272 assertNull("Expected null returned for Mixin type node", DataNormalizer.toLegacy(outerListNode));
276 * Following data are constructed: <any-xml-data> <inner>
277 * <inner-leaf>inner-leaf-value</inner-leaf> </inner>
278 * <leaf>leaf-value</leaf> <any-xml-data>
281 public void testToLegacyNormalizedNodeWithAnyXml() {
283 Node<?> innerLeafChild = NodeFactory.createImmutableSimpleNode(ANY_XML_INNER_LEAF_QNAME, null,
285 CompositeNode innerContainer = NodeFactory.createImmutableCompositeNode(ANY_XML_INNER_QNAME, null,
286 Collections.<Node<?>> singletonList(innerLeafChild));
288 Node<?> leafChild = NodeFactory.createImmutableSimpleNode(ANY_XML_LEAF_QNAME, null, "leaf-value");
289 CompositeNode anyXmlNodeValue = NodeFactory.createImmutableCompositeNode(ANY_XML_DATA_QNAME, null,
290 Arrays.asList(leafChild, innerContainer));
292 AnyXmlNode testAnyXmlNode = Builders.anyXmlBuilder().withNodeIdentifier(new NodeIdentifier(TEST_QNAME))
293 .withValue(anyXmlNodeValue).build();
295 ContainerNode testContainerNode = Builders.containerBuilder()
296 .withNodeIdentifier(new NodeIdentifier(TEST_QNAME)).withChild(testAnyXmlNode).build();
298 DataNormalizer normalizer = new DataNormalizer(createTestContext());
299 Node<?> legacyNode = normalizer.toLegacy(YangInstanceIdentifier.builder().node(TEST_QNAME).build(), testContainerNode);
307 expectSimpleNode(ANY_XML_LEAF_QNAME, "leaf-value"),
308 expectCompositeNode(ANY_XML_INNER_QNAME,
309 expectSimpleNode(ANY_XML_INNER_LEAF_QNAME, "inner-leaf-value")))));
313 public void testToLegacyNormalizedNodeWithLeafLists() {
315 CompositeNodeBuilder<ImmutableCompositeNode> testBuilder = ImmutableCompositeNode.builder();
316 testBuilder.setQName(TEST_QNAME);
318 ListNodeBuilder<Object, LeafSetEntryNode<Object>> leafSetBuilder = Builders.leafSetBuilder()
319 .withNodeIdentifier(new NodeIdentifier(UNORDERED_LEAF_LIST_QNAME));
320 for (int i = 1; i <= 3; i++) {
321 leafSetBuilder.withChildValue("unordered-value" + i);
324 ListNodeBuilder<Object, LeafSetEntryNode<Object>> orderedLeafSetBuilder = Builders.orderedLeafSetBuilder()
325 .withNodeIdentifier(new NodeIdentifier(ORDERED_LEAF_LIST_QNAME));
326 for (int i = 3; i > 0; i--) {
327 orderedLeafSetBuilder.withChildValue("ordered-value" + i);
330 ContainerNode testContainerNode = Builders.containerBuilder()
331 .withNodeIdentifier(new NodeIdentifier(TEST_QNAME)).withChild(leafSetBuilder.build())
332 .withChild(orderedLeafSetBuilder.build()).build();
334 DataNormalizer normalizer = new DataNormalizer(createTestContext());
336 Node<?> legacyNode = normalizer.toLegacy(YangInstanceIdentifier.builder().node(TEST_QNAME).build(), testContainerNode);
340 expectCompositeNode(TEST_QNAME, expectSimpleNode(UNORDERED_LEAF_LIST_QNAME, "unordered-value1"),
341 expectSimpleNode(UNORDERED_LEAF_LIST_QNAME, "unordered-value2"),
342 expectSimpleNode(UNORDERED_LEAF_LIST_QNAME, "unordered-value3"),
343 expectSimpleNode(ORDERED_LEAF_LIST_QNAME, "ordered-value3"),
344 expectSimpleNode(ORDERED_LEAF_LIST_QNAME, "ordered-value2"),
345 expectSimpleNode(ORDERED_LEAF_LIST_QNAME, "ordered-value1")));
349 public void testToLegacyNormalizedNodeWithAugmentation() {
351 AugmentationNode augmentationNode = Builders.augmentationBuilder()
352 .withNodeIdentifier(new AugmentationIdentifier(Sets.newHashSet(AUGMENTED_LEAF_QNAME)))
353 .withChild(ImmutableNodes.leafNode(AUGMENTED_LEAF_QNAME, "augmented-value")).build();
355 ContainerNode outerContainerNode = Builders.containerBuilder()
356 .withNodeIdentifier(new NodeIdentifier(OUTER_CONTAINER_QNAME)).withChild(augmentationNode).build();
358 ContainerNode testContainerNode = Builders.containerBuilder()
359 .withNodeIdentifier(new NodeIdentifier(TEST_QNAME)).withChild(outerContainerNode).build();
361 DataNormalizer normalizer = new DataNormalizer(createTestContext());
363 Node<?> legacyNode = normalizer.toLegacy(YangInstanceIdentifier.builder().node(TEST_QNAME).build(), testContainerNode);
369 expectCompositeNode(OUTER_CONTAINER_QNAME,
370 expectSimpleNode(AUGMENTED_LEAF_QNAME, "augmented-value"))));
373 private boolean isOrdered(final QName nodeName) {
374 return ORDERED_LEAF_LIST_QNAME.equals(nodeName) || INNER_LIST_QNAME.equals(nodeName);
377 @SuppressWarnings("unchecked")
378 private void verifyLegacyNode(final Node<?> actual, final LegacyNodeData expNodeData) {
380 assertNotNull("Actual Node is null", actual);
381 assertTrue("Expected CompositeNode instance", actual instanceof CompositeNode);
382 CompositeNode actualCN = (CompositeNode) actual;
383 assertEquals("Node key", expNodeData.nodeKey, actualCN.getKey());
385 List<LegacyNodeData> expChildData = Lists.newArrayList();
386 List<LegacyNodeData> unorderdChildData = Lists.newArrayList();
387 for (LegacyNodeData data : (List<LegacyNodeData>) expNodeData.nodeData) {
388 if (isOrdered(data.nodeKey)) {
389 expChildData.add(data);
391 unorderdChildData.add(data);
395 Collections.sort(unorderdChildData, new Comparator<LegacyNodeData>() {
397 public int compare(final LegacyNodeData arg1, final LegacyNodeData arg2) {
398 if (!(arg1.nodeData instanceof List) && !(arg2.nodeData instanceof List)) {
399 // if neither is a list, just compare them
400 String str1 = arg1.nodeKey.getLocalName() + arg1.nodeData;
401 String str2 = arg2.nodeKey.getLocalName() + arg2.nodeData;
402 return str1.compareTo(str2);
403 } else if (arg1.nodeData instanceof List && arg2.nodeData instanceof List) {
404 // if both are lists, first check their local name
405 String str1 = arg1.nodeKey.getLocalName();
406 String str2 = arg2.nodeKey.getLocalName();
407 if (!str1.equals(str2)) {
408 return str1.compareTo(str2);
410 // if local names are the same, then look at the list contents
411 List<LegacyNodeData> l1 = (List<LegacyNodeData>) arg1.nodeData;
412 List<LegacyNodeData> l2 = (List<LegacyNodeData>) arg2.nodeData;
414 if (l1.size() != l2.size()) {
415 // if the sizes are different, use that
416 return l2.size() - l1.size();
418 // lastly sort and recursively check the list contents
419 Collections.sort(l1, this);
420 Collections.sort(l2, this);
422 for (int i = 0 ; i < l1.size() ; i++) {
423 int diff = this.compare(l1.get(i), l2.get(i));
431 } else if( arg1.nodeData instanceof List ) {
439 expChildData.addAll(unorderdChildData);
441 List<Node<?>> actualChildNodes = Lists.newArrayList();
442 List<Node<?>> unorderedChildNodes = Lists.newArrayList();
443 for (Node<?> node : actualCN.getValue()) {
444 if (isOrdered(node.getKey())) {
445 actualChildNodes.add(node);
447 unorderedChildNodes.add(node);
451 Collections.sort(unorderedChildNodes, new Comparator<Node<?>>() {
453 public int compare(final Node<?> n1, final Node<?> n2) {
454 if (n1 instanceof SimpleNode && n2 instanceof SimpleNode) {
455 // if they're SimpleNodes just compare their strings
456 String str1 = n1.getKey().getLocalName() + ((SimpleNode<?>)n1).getValue();
457 String str2 = n2.getKey().getLocalName() + ((SimpleNode<?>)n2).getValue();
458 return str1.compareTo(str2);
459 } else if (n1 instanceof CompositeNode && n2 instanceof CompositeNode) {
460 // if they're CompositeNodes, things are more interesting
461 String str1 = n1.getKey().getLocalName();
462 String str2 = n2.getKey().getLocalName();
463 if (!str1.equals(str2)) {
464 // if their local names differ, return that difference
465 return str1.compareTo(str2);
467 // otherwise, we need to look at their contents
468 ArrayList<Node<?>> l1 = new ArrayList<Node<?>>( ((CompositeNode)n1).getValue() );
469 ArrayList<Node<?>> l2 = new ArrayList<Node<?>>( ((CompositeNode)n2).getValue() );
471 if (l1.size() != l2.size()) {
472 // if they have different numbers of things in them return that
473 return l2.size() - l1.size();
475 // otherwise, compare the individual elements, first sort them
476 Collections.sort(l1, this);
477 Collections.sort(l2, this);
479 // then compare them individually
480 for(int i = 0 ; i < l2.size() ; i++) {
481 int diff = this.compare(l1.get(i), l2.get(i));
489 } else if (n1 instanceof CompositeNode && n2 instanceof SimpleNode) {
491 } else if (n2 instanceof CompositeNode && n1 instanceof SimpleNode) {
494 assertTrue("Expected either SimpleNodes CompositeNodes", false);
500 actualChildNodes.addAll(unorderedChildNodes);
502 for (Node<?> actualChild : actualChildNodes) {
503 LegacyNodeData expData = expChildData.isEmpty() ? null : expChildData.remove(0);
504 assertNotNull("Unexpected child node with key " + actualChild.getKey(), expData);
505 assertEquals("Child node QName", expData.nodeKey, actualChild.getKey());
507 if (expData.nodeData instanceof List) { // List represents a
509 verifyLegacyNode(actualChild, expData);
510 } else { // else a simple node
511 assertTrue("Expected SimpleNode instance", actualChild instanceof SimpleNode);
512 assertEquals("Child node value with key " + actualChild.getKey(), expData.nodeData,
513 ((SimpleNode<?>) actualChild).getValue());
517 if (!expChildData.isEmpty()) {
518 fail("Missing child nodes: " + expChildData);
522 private LegacyNodeData expectCompositeNode(final QName key, final LegacyNodeData... childData) {
523 return new LegacyNodeData(key, Lists.newArrayList(childData));
526 private LegacyNodeData expectSimpleNode(final QName key, final Object value) {
527 return new LegacyNodeData(key, value);
531 public void testToNormalizedCompositeNode() {
532 SchemaContext testCtx = createTestContext();
533 DataNormalizer normalizer = new DataNormalizer(testCtx);
535 CompositeNodeBuilder<ImmutableCompositeNode> testBuilder = ImmutableCompositeNode.builder();
536 testBuilder.setQName(TEST_QNAME);
538 CompositeNodeBuilder<ImmutableCompositeNode> outerListBuilder = ImmutableCompositeNode.builder();
539 outerListBuilder.setQName(OUTER_LIST_QNAME);
540 outerListBuilder.addLeaf(ID_QNAME, 10);
541 outerListBuilder.addLeaf(ONE_QNAME, "one");
543 for (int i = 3; i > 0; i--) {
544 CompositeNodeBuilder<ImmutableCompositeNode> innerListBuilder = ImmutableCompositeNode.builder();
545 innerListBuilder.setQName(INNER_LIST_QNAME);
546 innerListBuilder.addLeaf(NAME_QNAME, "inner-name" + i);
547 innerListBuilder.addLeaf(VALUE_QNAME, "inner-value" + i);
548 outerListBuilder.add(innerListBuilder.toInstance());
551 testBuilder.add(outerListBuilder.toInstance());
553 outerListBuilder = ImmutableCompositeNode.builder();
554 outerListBuilder.setQName(OUTER_LIST_QNAME);
555 outerListBuilder.addLeaf(ID_QNAME, 20);
556 outerListBuilder.addLeaf(TWO_QNAME, "two");
557 outerListBuilder.addLeaf(THREE_QNAME, "three");
558 testBuilder.add(outerListBuilder.toInstance());
560 for (int i = 1; i <= 2; i++) {
561 CompositeNodeBuilder<ImmutableCompositeNode> unkeyedListBuilder = ImmutableCompositeNode.builder();
562 unkeyedListBuilder.setQName(UNKEYED_LIST_QNAME);
563 unkeyedListBuilder.addLeaf(NAME_QNAME, "unkeyed-name" + i);
564 testBuilder.add(unkeyedListBuilder.toInstance());
567 Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNodeEntry = normalizer
568 .toNormalized(new AbstractMap.SimpleEntry<YangInstanceIdentifier, CompositeNode>(YangInstanceIdentifier.create(
569 ImmutableList.<PathArgument> of(new NodeIdentifier(TEST_QNAME))), testBuilder.toInstance()));
571 verifyNormalizedInstanceIdentifier(normalizedNodeEntry.getKey(), TEST_QNAME);
573 verifyNormalizedNode(
574 normalizedNodeEntry.getValue(),
583 expectLeafNode(ID_QNAME, 10),
584 expectChoiceNode(OUTER_CHOICE_QNAME, expectLeafNode(ONE_QNAME, "one")),
585 expectOrderedMapNode(
587 expectMapEntryNode(INNER_LIST_QNAME, NAME_QNAME, "inner-name3",
588 expectLeafNode(NAME_QNAME, "inner-name3"),
589 expectLeafNode(VALUE_QNAME, "inner-value3")),
590 expectMapEntryNode(INNER_LIST_QNAME, NAME_QNAME, "inner-name2",
591 expectLeafNode(NAME_QNAME, "inner-name2"),
592 expectLeafNode(VALUE_QNAME, "inner-value2")),
593 expectMapEntryNode(INNER_LIST_QNAME, NAME_QNAME, "inner-name1",
594 expectLeafNode(NAME_QNAME, "inner-name1"),
595 expectLeafNode(VALUE_QNAME, "inner-value1")))),
600 expectLeafNode(ID_QNAME, 20),
601 expectChoiceNode(OUTER_CHOICE_QNAME, expectLeafNode(TWO_QNAME, "two"),
602 expectLeafNode(THREE_QNAME, "three")))),
603 expectUnkeyedListNode(
605 expectUnkeyedListEntryNode(UNKEYED_LIST_QNAME,
606 expectLeafNode(NAME_QNAME, "unkeyed-name1")),
607 expectUnkeyedListEntryNode(UNKEYED_LIST_QNAME,
608 expectLeafNode(NAME_QNAME, "unkeyed-name2")))));
612 public void testToNormalizedCompositeNodeWithAnyXml() {
613 SchemaContext testCtx = createTestContext();
614 DataNormalizer normalizer = new DataNormalizer(testCtx);
616 CompositeNodeBuilder<ImmutableCompositeNode> testBuilder = ImmutableCompositeNode.builder();
617 testBuilder.setQName(TEST_QNAME);
619 CompositeNodeBuilder<ImmutableCompositeNode> anyXmlBuilder = ImmutableCompositeNode.builder();
620 anyXmlBuilder.setQName(ANY_XML_DATA_QNAME);
621 anyXmlBuilder.addLeaf(ANY_XML_LEAF_QNAME, "leaf-value");
623 CompositeNodeBuilder<ImmutableCompositeNode> innerBuilder = ImmutableCompositeNode.builder();
624 innerBuilder.setQName(ANY_XML_INNER_QNAME);
625 innerBuilder.addLeaf(ANY_XML_INNER_LEAF_QNAME, "inner-leaf-value");
627 anyXmlBuilder.add(innerBuilder.toInstance());
628 CompositeNode anyXmlLegacy = anyXmlBuilder.toInstance();
629 testBuilder.add(anyXmlLegacy);
631 Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNodeEntry = normalizer
632 .toNormalized(new AbstractMap.SimpleEntry<YangInstanceIdentifier, CompositeNode>(YangInstanceIdentifier.create(
633 ImmutableList.<PathArgument> of(new NodeIdentifier(TEST_QNAME))), testBuilder.toInstance()));
635 verifyNormalizedInstanceIdentifier(normalizedNodeEntry.getKey(), TEST_QNAME);
637 verifyNormalizedNode(normalizedNodeEntry.getValue(),
638 expectContainerNode(TEST_QNAME, expectAnyXmlNode(ANY_XML_DATA_QNAME, anyXmlLegacy)));
642 public void testToNormalizedCompositeNodeWithAugmentation() {
643 SchemaContext testCtx = createTestContext();
644 DataNormalizer normalizer = new DataNormalizer(testCtx);
646 CompositeNodeBuilder<ImmutableCompositeNode> testBuilder = ImmutableCompositeNode.builder();
647 testBuilder.setQName(TEST_QNAME);
649 CompositeNodeBuilder<ImmutableCompositeNode> outerContBuilder = ImmutableCompositeNode.builder();
650 outerContBuilder.setQName(OUTER_CONTAINER_QNAME);
651 outerContBuilder.addLeaf(AUGMENTED_LEAF_QNAME, "augmented-value");
653 testBuilder.add(outerContBuilder.toInstance());
655 Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNodeEntry = normalizer
656 .toNormalized(new AbstractMap.SimpleEntry<YangInstanceIdentifier, CompositeNode>(YangInstanceIdentifier.create(
657 ImmutableList.<PathArgument> of(new NodeIdentifier(TEST_QNAME))), testBuilder.toInstance()));
659 verifyNormalizedInstanceIdentifier(normalizedNodeEntry.getKey(), TEST_QNAME);
661 NormalizedNodeData expAugmentation = expectAugmentation(AUGMENTED_LEAF_QNAME,
662 expectLeafNode(AUGMENTED_LEAF_QNAME, "augmented-value"));
664 verifyNormalizedNode(normalizedNodeEntry.getValue(),
665 expectContainerNode(TEST_QNAME, expectContainerNode(OUTER_CONTAINER_QNAME, expAugmentation)));
667 normalizedNodeEntry = normalizer.toNormalized(new AbstractMap.SimpleEntry<YangInstanceIdentifier, CompositeNode>(
668 YangInstanceIdentifier.create(Lists.newArrayList(new NodeIdentifier(TEST_QNAME), new NodeIdentifier(
669 OUTER_CONTAINER_QNAME))), outerContBuilder.toInstance()));
674 public void testToNormalizedCompositeNodeWithLeafLists() {
675 SchemaContext testCtx = createTestContext();
676 DataNormalizer normalizer = new DataNormalizer(testCtx);
678 CompositeNodeBuilder<ImmutableCompositeNode> testBuilder = ImmutableCompositeNode.builder();
679 testBuilder.setQName(TEST_QNAME);
681 for (int i = 1; i <= 3; i++) {
682 testBuilder.addLeaf(UNORDERED_LEAF_LIST_QNAME, "unordered-value" + i);
685 for (int i = 3; i > 0; i--) {
686 testBuilder.addLeaf(ORDERED_LEAF_LIST_QNAME, "ordered-value" + i);
689 Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNodeEntry = normalizer
690 .toNormalized(new AbstractMap.SimpleEntry<YangInstanceIdentifier, CompositeNode>(YangInstanceIdentifier.create(
691 ImmutableList.<PathArgument> of(new NodeIdentifier(TEST_QNAME))), testBuilder.toInstance()));
693 verifyNormalizedInstanceIdentifier(normalizedNodeEntry.getKey(), TEST_QNAME);
695 verifyNormalizedNode(
696 normalizedNodeEntry.getValue(),
699 expectLeafSetNode(UNORDERED_LEAF_LIST_QNAME,
700 expectLeafSetEntryNode(UNORDERED_LEAF_LIST_QNAME, "unordered-value1"),
701 expectLeafSetEntryNode(UNORDERED_LEAF_LIST_QNAME, "unordered-value2"),
702 expectLeafSetEntryNode(UNORDERED_LEAF_LIST_QNAME, "unordered-value3")),
703 expectOrderedLeafSetNode(ORDERED_LEAF_LIST_QNAME,
704 expectLeafSetEntryNode(ORDERED_LEAF_LIST_QNAME, "ordered-value3"),
705 expectLeafSetEntryNode(ORDERED_LEAF_LIST_QNAME, "ordered-value2"),
706 expectLeafSetEntryNode(ORDERED_LEAF_LIST_QNAME, "ordered-value1"))));
709 @SuppressWarnings("unchecked")
710 private void verifyNormalizedNode(final NormalizedNode<?, ?> actual, final NormalizedNodeData expNodeData) {
712 Class<?> expNodeClass = expNodeData.nodeClass;
713 PathArgument expNodeID = expNodeData.nodeID;
715 assertNotNull("Actual NormalizedNode is null", actual);
716 assertTrue("NormalizedNode instance " + actual.getClass() + " is not derived from " + expNodeClass,
717 expNodeClass.isAssignableFrom(actual.getClass()));
718 assertEquals("NormalizedNode identifier", expNodeID, actual.getIdentifier());
720 if (expNodeData.nodeData instanceof List) {
721 Map<PathArgument, Integer> orderingMap = null;
722 if (expNodeClass.equals(OrderedMapNode.class) || expNodeClass.equals(OrderedLeafSetNode.class)) {
723 orderingMap = Maps.newHashMap();
727 Map<PathArgument, NormalizedNodeData> expChildDataMap = Maps.newHashMap();
728 List<NormalizedNodeData> expChildDataList = (List<NormalizedNodeData>) expNodeData.nodeData;
729 for (NormalizedNodeData data : expChildDataList) {
730 expChildDataMap.put(data.nodeID, data);
732 if (orderingMap != null) {
733 orderingMap.put(data.nodeID, i++);
737 assertNotNull("Actual value is null for node " + actual.getIdentifier(), actual.getValue());
738 assertTrue("Expected value instance Iterable for node " + actual.getIdentifier(),
739 Iterable.class.isAssignableFrom(actual.getValue().getClass()));
742 for (NormalizedNode<?, ?> actualChild : (Iterable<NormalizedNode<?, ?>>) actual.getValue()) {
743 NormalizedNodeData expChildData = expNodeClass.equals(UnkeyedListNode.class) ? expChildDataList
744 .remove(0) : expChildDataMap.remove(actualChild.getIdentifier());
747 "Unexpected child node " + actualChild.getClass() + " with identifier "
748 + actualChild.getIdentifier() + " for parent node " + actual.getClass()
749 + " with identifier " + actual.getIdentifier(), expChildData);
751 if (orderingMap != null) {
752 assertEquals("Order index for child node " + actualChild.getIdentifier(),
753 orderingMap.get(actualChild.getIdentifier()), Integer.valueOf(i));
756 verifyNormalizedNode(actualChild, expChildData);
760 if (expNodeClass.equals(UnkeyedListNode.class)) {
761 if (expChildDataList.size() > 0) {
762 fail("Missing " + expChildDataList.size() + " child nodes for parent " + actual.getIdentifier());
765 if (!expChildDataMap.isEmpty()) {
766 fail("Missing child nodes for parent " + actual.getIdentifier() + ": " + expChildDataMap.keySet());
770 assertEquals("Leaf value for node " + actual.getIdentifier(), expNodeData.nodeData, actual.getValue());
774 private NormalizedNodeData expectOrderedLeafSetNode(final QName nodeName, final NormalizedNodeData... childData) {
775 return new NormalizedNodeData(new NodeIdentifier(nodeName), OrderedLeafSetNode.class,
776 Lists.newArrayList(childData));
779 private NormalizedNodeData expectLeafSetNode(final QName nodeName, final NormalizedNodeData... childData) {
780 return new NormalizedNodeData(new NodeIdentifier(nodeName), LeafSetNode.class, Lists.newArrayList(childData));
783 private NormalizedNodeData expectLeafSetEntryNode(final QName nodeName, final Object value) {
784 return new NormalizedNodeData(new NodeWithValue(nodeName, value), LeafSetEntryNode.class, value);
787 private NormalizedNodeData expectUnkeyedListNode(final QName nodeName, final NormalizedNodeData... childData) {
788 return new NormalizedNodeData(new NodeIdentifier(nodeName), UnkeyedListNode.class,
789 Lists.newArrayList(childData));
792 private NormalizedNodeData expectUnkeyedListEntryNode(final QName nodeName, final NormalizedNodeData... childData) {
793 return new NormalizedNodeData(new NodeIdentifier(nodeName), UnkeyedListEntryNode.class,
794 Lists.newArrayList(childData));
797 private NormalizedNodeData expectAugmentation(final QName augmentedNodeName, final NormalizedNodeData... childData) {
798 return new NormalizedNodeData(new AugmentationIdentifier(Sets.newHashSet(augmentedNodeName)),
799 AugmentationNode.class, Lists.newArrayList(childData));
802 private NormalizedNodeData expectAnyXmlNode(final QName nodeName, final Object value) {
803 return new NormalizedNodeData(new NodeIdentifier(nodeName), AnyXmlNode.class, value);
806 private NormalizedNodeData expectContainerNode(final QName nodeName, final NormalizedNodeData... childData) {
807 return new NormalizedNodeData(new NodeIdentifier(nodeName), ContainerNode.class, Lists.newArrayList(childData));
810 private NormalizedNodeData expectChoiceNode(final QName nodeName, final NormalizedNodeData... childData) {
811 return new NormalizedNodeData(new NodeIdentifier(nodeName), ChoiceNode.class, Lists.newArrayList(childData));
814 private NormalizedNodeData expectLeafNode(final QName nodeName, final Object value) {
815 return new NormalizedNodeData(new NodeIdentifier(nodeName), LeafNode.class, value);
819 private NormalizedNodeData expectMapEntryNode(final QName nodeName, final QName key, final Object value,
820 final NormalizedNodeData... childData) {
821 return new NormalizedNodeData(new NodeIdentifierWithPredicates(nodeName, key, value), MapEntryNode.class,
822 Lists.newArrayList(childData));
825 private NormalizedNodeData expectMapNode(final QName key, final NormalizedNodeData... childData) {
826 return new NormalizedNodeData(new NodeIdentifier(key), MapNode.class, Lists.newArrayList(childData));
829 private NormalizedNodeData expectOrderedMapNode(final QName key, final NormalizedNodeData... childData) {
830 return new NormalizedNodeData(new NodeIdentifier(key), OrderedMapNode.class, Lists.newArrayList(childData));