Make sure we compare key members via their property name 53/76653/1
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 4 Oct 2018 15:17:42 +0000 (17:17 +0200)
committerRobert Varga <nite@hq.sk>
Thu, 4 Oct 2018 15:40:05 +0000 (15:40 +0000)
As it turns out, simple comparison ignoring cases does not correctly
work if the schema is using CamelCase. We need to do the hard work of
deriving Binding property name and sort on that to be consistent with
what the codegen does.

JIRA: MDSAL-355
Change-Id: I34cdb032fbdeb093e2973b91c5011e302e6280bc
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/IdentifiableItemCodec.java
binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/test/InstanceIdentifierTest.java
binding/mdsal-binding-test-model/src/main/yang/mdsal-355.yang [new file with mode: 0644]

index 92185cd2f1537c3ad7c46b5bdf04590dfb34eca0..8e06d5ae548cb5d98d513a7900cc3734a9390889 100644 (file)
@@ -14,10 +14,12 @@ import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.reflect.Constructor;
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import org.opendaylight.mdsal.binding.spec.naming.BindingMapping;
 import org.opendaylight.yangtools.concepts.Codec;
 import org.opendaylight.yangtools.yang.binding.Identifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem;
@@ -63,7 +65,7 @@ final class IdentifiableItemCodec implements Codec<NodeIdentifierWithPredicates,
          *
          * We do not have to perform a sort if the source collection has less than two
          * elements.
-
+         *
          * We always perform an ImmutableList.copyOf(), as that will turn into a no-op
          * if the source is already immutable. It will also produce optimized implementations
          * for empty and singleton collections.
@@ -74,7 +76,8 @@ final class IdentifiableItemCodec implements Codec<NodeIdentifierWithPredicates,
         final List<QName> sortedKeys;
         if (unsortedKeys.size() > 1) {
             final List<QName> tmp = new ArrayList<>(unsortedKeys);
-            tmp.sort((q1, q2) -> q1.getLocalName().compareToIgnoreCase(q2.getLocalName()));
+            // This is not terribly efficient but gets the job done
+            tmp.sort(Comparator.comparing(qname -> BindingMapping.getPropertyName(qname.getLocalName())));
             sortedKeys = tmp;
         } else {
             sortedKeys = unsortedKeys;
index ae3cb9f745d526d91a78290f1fbc713b98b7b200..35ddbb20a7726067a05385cac1b9380164611028 100644 (file)
@@ -10,16 +10,23 @@ package org.opendaylight.mdsal.binding.dom.codec.test;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
+import com.google.common.collect.ImmutableMap;
 import org.junit.Test;
+import org.opendaylight.yang.gen.v1.mdsal._355.norev.OspfStatLsdbBrief;
+import org.opendaylight.yang.gen.v1.mdsal._355.norev.OspfStatLsdbBriefKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.TreeComplexUsesAugment;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.TreeLeafOnlyAugment;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.Top;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelListKey;
+import org.opendaylight.yangtools.yang.binding.Identifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 
 public class InstanceIdentifierTest extends AbstractBindingCodecTest {
@@ -49,4 +56,17 @@ public class InstanceIdentifierTest extends AbstractBindingCodecTest {
         assertTrue(((AugmentationIdentifier) leafOnlyLastArg).getPossibleChildNames().contains(SIMPLE_VALUE_QNAME));
     }
 
+    @Test
+    public void testCamelCaseKeys() {
+        final InstanceIdentifier<?> result = registry.fromYangInstanceIdentifier(YangInstanceIdentifier.create(
+            NodeIdentifier.create(OspfStatLsdbBrief.QNAME),
+            new NodeIdentifierWithPredicates(OspfStatLsdbBrief.QNAME, ImmutableMap.of(
+                QName.create(OspfStatLsdbBrief.QNAME, "AreaIndex"), 1,
+                QName.create(OspfStatLsdbBrief.QNAME, "LsaType"), (short) 2,
+                QName.create(OspfStatLsdbBrief.QNAME, "LsId"), 3,
+                QName.create(OspfStatLsdbBrief.QNAME, "AdvRtr"), "foo"))));
+        assertTrue(result instanceof KeyedInstanceIdentifier);
+        final Identifier<?> key = ((KeyedInstanceIdentifier<?, ?>) result).getKey();
+        assertEquals(new OspfStatLsdbBriefKey("foo", 1, 3, (short)2), key);
+    }
 }
diff --git a/binding/mdsal-binding-test-model/src/main/yang/mdsal-355.yang b/binding/mdsal-binding-test-model/src/main/yang/mdsal-355.yang
new file mode 100644 (file)
index 0000000..a1effc5
--- /dev/null
@@ -0,0 +1,13 @@
+module mdsal-355 {
+       namespace "mdsal-355";
+       prefix "mdsal355";
+
+    list OspfStatLsdbBrief {
+        key "AreaIndex LsaType LsId AdvRtr";
+        leaf AreaIndex { type int32; description "Area Index"; }
+        leaf LsaType { type uint8; description "LSA Type"; }
+        leaf LsId { type int32; description "LSA ID"; }
+        leaf AdvRtr { type string; description "Advertised Router"; }
+    }
+}
+