Fix bits/instance-identifier value serdes 45/103945/18
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 6 Jan 2023 15:30:27 +0000 (16:30 +0100)
committerRobert Varga <nite@hq.sk>
Wed, 15 Mar 2023 13:17:16 +0000 (13:17 +0000)
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>
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 51aaf19e594a35046ce1fb8264af54577120c8c3..ab3678ae995fbe94adac39c64e0d0e1895399fba 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 @@ 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[foo:id=\"/foo:bar[foo:qname='bar:two']\"]",
             buildYangInstanceIdentifier(FOO_BAZ, FOO_ID, buildYangInstanceIdentifier(FOO_BAR, FOO_QNAME, BAR_TWO)));
@@ -111,7 +109,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[foo:qname='foo:one']\"]",
             buildYangInstanceIdentifier(BAR_BAR, buildYangInstanceIdentifier(FOO_BAR, FOO_QNAME, FOO_ONE)));
@@ -120,7 +117,6 @@ class YT1473Test {
     }
 
     @Test
-    @Disabled("YT-1473: bits values need to be recognized and properly encoded and escaped")
     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 @@ class YT1473Test {
     }
 
     @Test
-    @Disabled("YT-1473: bits values need to be recognized and properly encoded and escaped")
     void testSerializeBitsValue() throws Exception {
         assertSerdes("/bar:bee[.='']", buildYangInstanceIdentifier(BAR_BEE, ImmutableSet.of()));
         assertSerdes("/bar:bee[.='one']", buildYangInstanceIdentifier(BAR_BEE, ImmutableSet.of("one")));
index a89ae431a80f5e54267618e893039a8df3fc4cd4..4e3fbbe36823d97a77b2cfa80807373d631070bc 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,23 @@ public abstract class AbstractStringInstanceIdentifierCodec extends AbstractName
             // QName implies identity-ref, which can never be escaped
             return appendQName(sb.append('\''), qname, currentModule).append('\'');
         }
+        // FIXME: YANGTOOLS-1426: update once we have a dedicated type
+        if (value instanceof Set<?> bits) {
+            // 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 var str = value instanceof YangInstanceIdentifier id ? serialize(id) : String.valueOf(value);
 
         // We have two specifications here: Section 6.1.3 of both RFC6020 and RFC7950:
         //
@@ -161,4 +177,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 str) {
+            return str;
+        }
+        throw new IllegalArgumentException("Unexpected bits component " + obj);
+    }
 }