From 77f491931ec07f6972869b8cbfa2207857990cec Mon Sep 17 00:00:00 2001 From: Tom Pantelis Date: Fri, 19 Jan 2018 19:19:03 -0500 Subject: [PATCH] Handle empty type in NormalizedNode streaming The yang "empty" type is now represented as org.opendaylight.yangtools.yang.common.Empty so handle it. NormalizedNode no longer allows a null value but we still need to handle NULL_TYPE on input for backwards compatibility. NULL_TYPE is translated to Empty. Change-Id: I99b87138d7358d37170cf603d993cd1a4f6a2087 Signed-off-by: Tom Pantelis --- .../stream/AbstractNormalizedNodeDataOutput.java | 2 +- .../utils/stream/NormalizedNodeInputStreamReader.java | 10 ++++++++++ .../datastore/node/utils/stream/ValueTypes.java | 11 ++++++++--- .../stream/NormalizedNodeStreamReaderWriterTest.java | 2 ++ .../controller/cluster/datastore/util/TestModel.java | 1 + .../src/test/resources/odl-datastore-test.yang | 4 ++++ 6 files changed, 26 insertions(+), 4 deletions(-) diff --git a/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/AbstractNormalizedNodeDataOutput.java b/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/AbstractNormalizedNodeDataOutput.java index c4db272989..02bebebd29 100755 --- a/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/AbstractNormalizedNodeDataOutput.java +++ b/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/AbstractNormalizedNodeDataOutput.java @@ -484,7 +484,7 @@ abstract class AbstractNormalizedNodeDataOutput implements NormalizedNodeDataOut case ValueTypes.YANG_IDENTIFIER_TYPE: writeYangInstanceIdentifierInternal((YangInstanceIdentifier) value); break; - case ValueTypes.NULL_TYPE : + case ValueTypes.EMPTY_TYPE: break; case ValueTypes.STRING_BYTES_TYPE: final byte[] valueBytes = value.toString().getBytes(StandardCharsets.UTF_8); diff --git a/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/NormalizedNodeInputStreamReader.java b/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/NormalizedNodeInputStreamReader.java index 3b912e6cb9..cc744438ff 100755 --- a/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/NormalizedNodeInputStreamReader.java +++ b/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/NormalizedNodeInputStreamReader.java @@ -27,6 +27,7 @@ import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.dom.DOMSource; import org.opendaylight.controller.cluster.datastore.node.utils.QNameFactory; +import org.opendaylight.yangtools.yang.common.Empty; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; @@ -333,6 +334,15 @@ public class NormalizedNodeInputStreamReader implements NormalizedNodeDataInput case ValueTypes.YANG_IDENTIFIER_TYPE : return readYangInstanceIdentifierInternal(); + case ValueTypes.EMPTY_TYPE: + // Leaf nodes no longer allow null values and thus we no longer emit null values. Previously, the "empty" + // yang type was represented as null so we translate an incoming null value to Empty. It was possible for + // a BI user to set a string leaf to null and we're rolling the dice here but the chances for that are + // very low. We'd have to know the yang type but, even if we did, we can't let a null value pass upstream + // so we'd have to drop the leaf which might cause other issues. + case ValueTypes.NULL_TYPE: + return Empty.getInstance(); + default : return null; } diff --git a/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/ValueTypes.java b/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/ValueTypes.java index 190f5969aa..51ff8d3500 100644 --- a/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/ValueTypes.java +++ b/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/ValueTypes.java @@ -13,7 +13,9 @@ import com.google.common.collect.ImmutableMap.Builder; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Map; +import java.util.Objects; import java.util.Set; +import org.opendaylight.yangtools.yang.common.Empty; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; @@ -33,8 +35,12 @@ final class ValueTypes { public static final byte BIG_INTEGER_TYPE = 10; public static final byte BIG_DECIMAL_TYPE = 11; public static final byte BINARY_TYPE = 12; + // Leaf nodes no longer allow null values. The "empty" type is now represented as + // org.opendaylight.yangtools.yang.common.Empty. This is kept for backwards compatibility. + @Deprecated public static final byte NULL_TYPE = 13; public static final byte STRING_BYTES_TYPE = 14; + public static final byte EMPTY_TYPE = 15; private static final Map, Byte> TYPES; @@ -51,6 +57,7 @@ final class ValueTypes { b.put(BigInteger.class, BIG_INTEGER_TYPE); b.put(BigDecimal.class, BIG_DECIMAL_TYPE); b.put(byte[].class, BINARY_TYPE); + b.put(Empty.class, EMPTY_TYPE); TYPES = b.build(); } @@ -60,9 +67,7 @@ final class ValueTypes { } public static byte getSerializableType(Object node) { - if (node == null) { - return NULL_TYPE; - } + Objects.requireNonNull(node); final Byte type = TYPES.get(node.getClass()); if (type != null) { diff --git a/opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/NormalizedNodeStreamReaderWriterTest.java b/opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/NormalizedNodeStreamReaderWriterTest.java index e2e5aa4bef..147cc663d9 100644 --- a/opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/NormalizedNodeStreamReaderWriterTest.java +++ b/opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/NormalizedNodeStreamReaderWriterTest.java @@ -26,6 +26,7 @@ import org.apache.commons.lang.SerializationUtils; import org.junit.Assert; import org.junit.Test; import org.opendaylight.controller.cluster.datastore.util.TestModel; +import org.opendaylight.yangtools.yang.common.Empty; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; @@ -92,6 +93,7 @@ public class NormalizedNodeStreamReaderWriterTest { new NodeIdentifier(TestModel.BINARY_LEAF_LIST_QNAME)) .withChild(entry1).withChild(entry2).build()) .withChild(ImmutableNodes.leafNode(TestModel.SOME_BINARY_DATA_QNAME, new byte[]{1, 2, 3, 4})) + .withChild(ImmutableNodes.leafNode(TestModel.EMPTY_QNAME, Empty.getInstance())) .withChild(Builders.orderedMapBuilder() .withNodeIdentifier(new NodeIdentifier(TestModel.ORDERED_LIST_QNAME)) .withChild(ImmutableNodes.mapEntry(TestModel.ORDERED_LIST_ENTRY_QNAME, diff --git a/opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/util/TestModel.java b/opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/util/TestModel.java index 72b8a3bb7f..7cdd783995 100644 --- a/opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/util/TestModel.java +++ b/opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/util/TestModel.java @@ -94,6 +94,7 @@ public final class TestModel { public static final QName CHOICE_QNAME = QName.create(TEST_QNAME, "choice"); public static final QName SHOE_QNAME = QName.create(TEST_QNAME, "shoe"); public static final QName ANY_XML_QNAME = QName.create(TEST_QNAME, "any"); + public static final QName EMPTY_QNAME = QName.create(TEST_QNAME, "empty-leaf"); public static final QName INVALID_QNAME = QName.create(TEST_QNAME, "invalid"); private static final String DATASTORE_TEST_YANG = "/odl-datastore-test.yang"; private static final String DATASTORE_AUG_YANG = "/odl-datastore-augmentation.yang"; diff --git a/opendaylight/md-sal/sal-clustering-commons/src/test/resources/odl-datastore-test.yang b/opendaylight/md-sal/sal-clustering-commons/src/test/resources/odl-datastore-test.yang index 613288dadd..294b001a85 100644 --- a/opendaylight/md-sal/sal-clustering-commons/src/test/resources/odl-datastore-test.yang +++ b/opendaylight/md-sal/sal-clustering-commons/src/test/resources/odl-datastore-test.yang @@ -160,5 +160,9 @@ module odl-datastore-test { anyxml any { } + + leaf empty-leaf { + type empty; + } } } -- 2.36.6