From 875808f8ee0a6e2b6f63dfffcb0d5194136720fe Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Fri, 6 Jan 2023 16:30:27 +0100 Subject: [PATCH] Fix bits/instance-identifier value serdes 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 Signed-off-by: Ruslan Kashapov (cherry picked from commit b0d52d88a50259a179b0f128ba9c5e39f4dd30e9) --- .../yang/data/codec/gson/YT1473Test.java | 5 ---- .../yang/data/codec/xml/YT1473Test.java | 5 ---- ...AbstractStringInstanceIdentifierCodec.java | 28 ++++++++++++++++++- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/codec/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/YT1473Test.java b/codec/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/YT1473Test.java index 52e0fed732..44c5625495 100644 --- a/codec/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/YT1473Test.java +++ b/codec/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/YT1473Test.java @@ -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"))); diff --git a/codec/yang-data-codec-xml/src/test/java/org/opendaylight/yangtools/yang/data/codec/xml/YT1473Test.java b/codec/yang-data-codec-xml/src/test/java/org/opendaylight/yangtools/yang/data/codec/xml/YT1473Test.java index b887ac7864..df807605af 100644 --- a/codec/yang-data-codec-xml/src/test/java/org/opendaylight/yangtools/yang/data/codec/xml/YT1473Test.java +++ b/codec/yang-data-codec-xml/src/test/java/org/opendaylight/yangtools/yang/data/codec/xml/YT1473Test.java @@ -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"))); diff --git a/data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractStringInstanceIdentifierCodec.java b/data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractStringInstanceIdentifierCodec.java index f441dad6ba..33523b21f3 100644 --- a/data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractStringInstanceIdentifierCodec.java +++ b/data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractStringInstanceIdentifierCodec.java @@ -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); + } } -- 2.36.6