Handle empty type in NormalizedNode streaming
[controller.git] / opendaylight / md-sal / sal-clustering-commons / src / main / java / org / opendaylight / controller / cluster / datastore / node / utils / stream / NormalizedNodeInputStreamReader.java
old mode 100644 (file)
new mode 100755 (executable)
index ec04356..cc74443
@@ -17,6 +17,7 @@ import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -26,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;
@@ -39,6 +41,7 @@ import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Element;
@@ -72,16 +75,6 @@ public class NormalizedNodeInputStreamReader implements NormalizedNodeDataInput
 
     private boolean readSignatureMarker = true;
 
-    /**
-     * Constructs an instance.
-     *
-     * @deprecated Use {@link NormalizedNodeInputOutput#newDataInput(DataInput)} instead.
-     */
-    @Deprecated
-    public NormalizedNodeInputStreamReader(final DataInput input) {
-        this(input, false);
-    }
-
     NormalizedNodeInputStreamReader(final DataInput input, final boolean versionChecked) {
         this.input = Preconditions.checkNotNull(input);
         readSignatureMarker = !versionChecked;
@@ -115,7 +108,8 @@ public class NormalizedNodeInputStreamReader implements NormalizedNodeDataInput
         byte nodeType = input.readByte();
 
         if (nodeType == NodeTypes.END_NODE) {
-            LOG.debug("End node reached. return");
+            LOG.trace("End node reached. return");
+            lastLeafSetQName = null;
             return null;
         }
 
@@ -124,7 +118,7 @@ public class NormalizedNodeInputStreamReader implements NormalizedNodeDataInput
                 YangInstanceIdentifier.AugmentationIdentifier augIdentifier =
                     new YangInstanceIdentifier.AugmentationIdentifier(readQNameSet());
 
-                LOG.debug("Reading augmentation node {} ", augIdentifier);
+                LOG.trace("Reading augmentation node {} ", augIdentifier);
 
                 return addDataContainerChildren(Builders.augmentationBuilder()
                         .withNodeIdentifier(augIdentifier)).build();
@@ -138,7 +132,7 @@ public class NormalizedNodeInputStreamReader implements NormalizedNodeDataInput
                 Object value = readObject();
                 NodeWithValue<Object> leafIdentifier = new NodeWithValue<>(name, value);
 
-                LOG.debug("Reading leaf set entry node {}, value {}", leafIdentifier, value);
+                LOG.trace("Reading leaf set entry node {}, value {}", leafIdentifier, value);
 
                 return leafSetEntryBuilder().withNodeIdentifier(leafIdentifier).withValue(value).build();
 
@@ -146,7 +140,7 @@ public class NormalizedNodeInputStreamReader implements NormalizedNodeDataInput
                 NodeIdentifierWithPredicates entryIdentifier = new NodeIdentifierWithPredicates(
                         readQName(), readKeyValueMap());
 
-                LOG.debug("Reading map entry node {} ", entryIdentifier);
+                LOG.trace("Reading map entry node {} ", entryIdentifier);
 
                 return addDataContainerChildren(Builders.mapEntryBuilder()
                         .withNodeIdentifier(entryIdentifier)).build();
@@ -180,46 +174,46 @@ public class NormalizedNodeInputStreamReader implements NormalizedNodeDataInput
 
         switch (nodeType) {
             case NodeTypes.LEAF_NODE :
-                LOG.debug("Read leaf node {}", identifier);
+                LOG.trace("Read leaf node {}", identifier);
                 // Read the object value
                 return leafBuilder().withNodeIdentifier(identifier).withValue(readObject()).build();
 
             case NodeTypes.ANY_XML_NODE :
-                LOG.debug("Read xml node");
+                LOG.trace("Read xml node");
                 return Builders.anyXmlBuilder().withNodeIdentifier(identifier).withValue(readDOMSource()).build();
 
             case NodeTypes.MAP_NODE :
-                LOG.debug("Read map node {}", identifier);
+                LOG.trace("Read map node {}", identifier);
                 return addDataContainerChildren(Builders.mapBuilder().withNodeIdentifier(identifier)).build();
 
             case NodeTypes.CHOICE_NODE:
-                LOG.debug("Read choice node {}", identifier);
+                LOG.trace("Read choice node {}", identifier);
                 return addDataContainerChildren(Builders.choiceBuilder().withNodeIdentifier(identifier)).build();
 
             case NodeTypes.ORDERED_MAP_NODE:
-                LOG.debug("Reading ordered map node {}", identifier);
+                LOG.trace("Reading ordered map node {}", identifier);
                 return addDataContainerChildren(Builders.orderedMapBuilder().withNodeIdentifier(identifier)).build();
 
             case NodeTypes.UNKEYED_LIST:
-                LOG.debug("Read unkeyed list node {}", identifier);
+                LOG.trace("Read unkeyed list node {}", identifier);
                 return addDataContainerChildren(Builders.unkeyedListBuilder().withNodeIdentifier(identifier)).build();
 
             case NodeTypes.UNKEYED_LIST_ITEM:
-                LOG.debug("Read unkeyed list item node {}", identifier);
+                LOG.trace("Read unkeyed list item node {}", identifier);
                 return addDataContainerChildren(Builders.unkeyedListEntryBuilder()
                         .withNodeIdentifier(identifier)).build();
 
             case NodeTypes.CONTAINER_NODE:
-                LOG.debug("Read container node {}", identifier);
+                LOG.trace("Read container node {}", identifier);
                 return addDataContainerChildren(Builders.containerBuilder().withNodeIdentifier(identifier)).build();
 
             case NodeTypes.LEAF_SET :
-                LOG.debug("Read leaf set node {}", identifier);
+                LOG.trace("Read leaf set node {}", identifier);
                 return addLeafSetChildren(identifier.getNodeType(),
                         Builders.leafSetBuilder().withNodeIdentifier(identifier)).build();
 
             case NodeTypes.ORDERED_LEAF_SET:
-                LOG.debug("Read ordered leaf set node {}", identifier);
+                LOG.trace("Read ordered leaf set node {}", identifier);
                 ListNodeBuilder<Object, LeafSetEntryNode<Object>> orderedLeafSetBuilder =
                         Builders.orderedLeafSetBuilder().withNodeIdentifier(identifier);
                 orderedLeafSetBuilder = addLeafSetChildren(identifier.getNodeType(), orderedLeafSetBuilder);
@@ -268,7 +262,7 @@ public class NormalizedNodeInputStreamReader implements NormalizedNodeDataInput
             return codedStringMap.get(input.readInt());
         } else if (valueType == TokenTypes.IS_STRING_VALUE) {
             String value = input.readUTF().intern();
-            codedStringMap.put(Integer.valueOf(codedStringMap.size()), value);
+            codedStringMap.put(codedStringMap.size(), value);
             return value;
         }
 
@@ -303,22 +297,22 @@ public class NormalizedNodeInputStreamReader implements NormalizedNodeDataInput
                 return readObjSet();
 
             case ValueTypes.BOOL_TYPE :
-                return Boolean.valueOf(input.readBoolean());
+                return input.readBoolean();
 
             case ValueTypes.BYTE_TYPE :
-                return Byte.valueOf(input.readByte());
+                return input.readByte();
 
             case ValueTypes.INT_TYPE :
-                return Integer.valueOf(input.readInt());
+                return input.readInt();
 
             case ValueTypes.LONG_TYPE :
-                return Long.valueOf(input.readLong());
+                return input.readLong();
 
             case ValueTypes.QNAME_TYPE :
                 return readQName();
 
             case ValueTypes.SHORT_TYPE :
-                return Short.valueOf(input.readShort());
+                return input.readShort();
 
             case ValueTypes.STRING_TYPE :
                 return input.readUTF();
@@ -340,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;
         }
@@ -351,6 +354,20 @@ public class NormalizedNodeInputStreamReader implements NormalizedNodeDataInput
         return new String(bytes, StandardCharsets.UTF_8);
     }
 
+    @Override
+    public SchemaPath readSchemaPath() throws IOException {
+        readSignatureMarkerAndVersionIfNeeded();
+
+        final boolean absolute = input.readBoolean();
+        final int size = input.readInt();
+        final Collection<QName> qnames = new ArrayList<>(size);
+        for (int i = 0; i < size; ++i) {
+            qnames.add(readQName());
+        }
+
+        return SchemaPath.create(qnames, absolute);
+    }
+
     @Override
     public YangInstanceIdentifier readYangInstanceIdentifier() throws IOException {
         readSignatureMarkerAndVersionIfNeeded();
@@ -405,7 +422,7 @@ public class NormalizedNodeInputStreamReader implements NormalizedNodeDataInput
     private ListNodeBuilder<Object, LeafSetEntryNode<Object>> addLeafSetChildren(final QName nodeType,
             final ListNodeBuilder<Object, LeafSetEntryNode<Object>> builder) throws IOException {
 
-        LOG.debug("Reading children of leaf set");
+        LOG.trace("Reading children of leaf set");
 
         lastLeafSetQName = nodeType;
 
@@ -421,7 +438,7 @@ public class NormalizedNodeInputStreamReader implements NormalizedNodeDataInput
     @SuppressWarnings({ "unchecked", "rawtypes" })
     private NormalizedNodeContainerBuilder addDataContainerChildren(
             final NormalizedNodeContainerBuilder builder) throws IOException {
-        LOG.debug("Reading data container (leaf nodes) nodes");
+        LOG.trace("Reading data container (leaf nodes) nodes");
 
         NormalizedNode<?, ?> child = readNormalizedNodeInternal();