Fix bits/instance-identifier value serdes 72/104872/3
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 6 Jan 2023 15:30:27 +0000 (16:30 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 15 Mar 2023 23:14:10 +0000 (00:14 +0100)
Bits and instance-identifier values need to be recognized. Fix their
serialization and parsing and enable tests.

JIRA: YANGTOOLS-1473
Change-Id: If5b40d4642e4d8353e8dfad492166987fc3c536b
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
Signed-off-by: Ruslan Kashapov <ruslan.kashapov@pantheon.tech>
(cherry picked from commit b0d52d88a50259a179b0f128ba9c5e39f4dd30e9)

codec/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/YT1473Test.java
codec/yang-data-codec-xml/src/test/java/org/opendaylight/yangtools/yang/data/codec/xml/YT1473Test.java
data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractStringInstanceIdentifierCodec.java

index 52e0fed7325cc0900c0e64d2fa302dca85203eb7..44c56254953bc4d131202288940ee3c467c6b22d 100644 (file)
@@ -18,7 +18,6 @@ import com.google.common.collect.ImmutableSet;
 import com.google.gson.stream.JsonWriter;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 import org.mockito.ArgumentCaptor;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -103,7 +102,6 @@ class YT1473Test {
     }
 
     @Test
-    @Disabled("YT-1473: Instance-identifier values need to be recognized and properly encoded and escaped")
     void testSerializeInstanceIdentifierRef() throws Exception {
         assertSerdes("/foo:baz[id=\"/foo:bar[qname='bar:two']\"]",
             buildYangInstanceIdentifier(FOO_BAZ, FOO_ID, buildYangInstanceIdentifier(FOO_BAR, FOO_QNAME, BAR_TWO)));
@@ -116,7 +114,6 @@ class YT1473Test {
     }
 
     @Test
-    @Disabled("YT-1473: Instance-identifier values need to be recognized and properly encoded and escaped")
     void testSerializeInstanceIdentifierValue() throws Exception {
         assertSerdes("/bar:bar[.=\"/foo:bar[qname='bar:two']\"]",
             buildYangInstanceIdentifier(BAR_BAR, buildYangInstanceIdentifier(FOO_BAR, FOO_QNAME, BAR_TWO)));
@@ -125,7 +122,6 @@ class YT1473Test {
     }
 
     @Test
-    @Disabled("YT-1473: bits values need to be recognized and properly encoded")
     void testSerializeBits() throws Exception {
         assertSerdes("/foo:bee[bts='']", buildYangInstanceIdentifier(FOO_BEE, FOO_BTS, ImmutableSet.of()));
         assertSerdes("/foo:bee[bts='one']", buildYangInstanceIdentifier(FOO_BEE, FOO_BTS, ImmutableSet.of("one")));
@@ -134,7 +130,6 @@ class YT1473Test {
     }
 
     @Test
-    @Disabled("YT-1473: bits values need to be recognized and properly encoded")
     void testSerializeBitsValue() throws Exception {
         assertSerdes("/bar:bee[.='']", buildYangInstanceIdentifier(BAR_BEE, ImmutableSet.of()));
         assertSerdes("/bar:bee[.='one']", buildYangInstanceIdentifier(BAR_BEE, ImmutableSet.of("one")));
index b887ac786435b82b25f57815d92be1771c47ae37..df807605af19218a0d0f01c84d9eee09fa292300 100644 (file)
@@ -18,7 +18,6 @@ import javax.xml.namespace.NamespaceContext;
 import javax.xml.stream.XMLStreamWriter;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 import org.mockito.ArgumentCaptor;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -98,7 +97,6 @@ public class YT1473Test {
     }
 
     @Test
-    @Disabled("YT-1473: Instance-identifier values need to be recognized and properly encoded and escaped")
     public void testSerializeInstanceIdentifierRef() throws Exception {
         assertSerdes("/foo:baz[foo:id=\"/foo:bar[foo:qname='bar:two']\"]",
             buildYangInstanceIdentifier(FOO_BAZ, FOO_ID, buildYangInstanceIdentifier(FOO_BAR, FOO_QNAME, BAR_TWO)));
@@ -111,7 +109,6 @@ public class YT1473Test {
     }
 
     @Test
-    @Disabled("YT-1473: Instance-identifier values need to be recognized and properly encoded and escaped")
     public void testSerializeInstanceIdentifierValue() throws Exception {
         assertSerdes("/bar:bar[.=\"/foo:bar[foo:qname='foo:one']\"]",
             buildYangInstanceIdentifier(BAR_BAR, buildYangInstanceIdentifier(FOO_BAR, FOO_QNAME, FOO_ONE)));
@@ -120,7 +117,6 @@ public class YT1473Test {
     }
 
     @Test
-    @Disabled("YT-1473: bits values need to be recognized and properly encoded and escaped")
     public void testSerializeBits() throws Exception {
         assertSerdes("/foo:bee[foo:bts='']", buildYangInstanceIdentifier(FOO_BEE, FOO_BTS, ImmutableSet.of()));
         assertSerdes("/foo:bee[foo:bts='one']", buildYangInstanceIdentifier(FOO_BEE, FOO_BTS, ImmutableSet.of("one")));
@@ -129,7 +125,6 @@ public class YT1473Test {
     }
 
     @Test
-    @Disabled("YT-1473: bits values need to be recognized and properly encoded and escaped")
     public void testSerializeBitsValue() throws Exception {
         assertSerdes("/bar:bee[.='']", buildYangInstanceIdentifier(BAR_BEE, ImmutableSet.of()));
         assertSerdes("/bar:bee[.='one']", buildYangInstanceIdentifier(BAR_BEE, ImmutableSet.of("one")));
index f441dad6ba6d38e3355505b007fdabd3717244ec..33523b21f3e9de4eeaef86ef765b68b8e493aba8 100644 (file)
@@ -13,6 +13,7 @@ import static java.util.Objects.requireNonNull;
 import com.google.common.annotations.Beta;
 import com.google.common.escape.Escaper;
 import com.google.common.escape.Escapers;
+import java.util.Set;
 import javax.xml.XMLConstants;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
@@ -85,8 +86,25 @@ public abstract class AbstractStringInstanceIdentifierCodec extends AbstractName
             // QName implies identity-ref, which can never be escaped
             return appendQName(sb.append('\''), (QName) value, currentModule).append('\'');
         }
+        // FIXME: YANGTOOLS-1426: update once we have a dedicated type
+        if (value instanceof Set) {
+            final var bits = (Set<?>) value;
+            // Set implies bits, which can never be escaped and need to be serialized as space-separated items
+            sb.append('\'');
 
-        final var str = String.valueOf(value);
+            final var it = bits.iterator();
+            if (it.hasNext()) {
+                sb.append(checkBitsItem(it.next()));
+                while (it.hasNext()) {
+                    sb.append(' ').append(checkBitsItem(it.next()));
+                }
+            }
+
+            return sb.append('\'');
+        }
+
+        final String str = value instanceof YangInstanceIdentifier ? serialize((YangInstanceIdentifier) value)
+            : String.valueOf(value);
 
         // We have two specifications here: Section 6.1.3 of both RFC6020 and RFC7950:
         //
@@ -161,4 +179,12 @@ public abstract class AbstractStringInstanceIdentifierCodec extends AbstractName
         // which is the same thing: always encode prefixes
         return createQName(XMLConstants.DEFAULT_NS_PREFIX, localName);
     }
+
+    // FIXME: YANGTOOLS-1426: this will not be necessary when we have dedicated bits type
+    private static @NonNull String checkBitsItem(final Object obj) {
+        if (obj instanceof String) {
+            return (String) obj;
+        }
+        throw new IllegalArgumentException("Unexpected bits component " + obj);
+    }
 }