Add uint adaptation to AbstractNormalizedNodePruner 16/84716/3
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 25 Sep 2019 15:34:53 +0000 (17:34 +0200)
committerRobert Varga <nite@hq.sk>
Fri, 27 Sep 2019 05:22:36 +0000 (05:22 +0000)
When migrating from old snapshots to magnesium format we have to
make sure we also legacy uint mapped values, so that after recovery
we end up with proper types being present.

JIRA: CONTROLLER-1919
Change-Id: I86ee49efee0d6c0519680197ea3e3985b1566e0c
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/transformer/AbstractNormalizedNodePruner.java
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/transformer/ReusableNormalizedNodePruner.java

index a6d8801d77b797f1cb850a73eb2c05dac8cd5ab5..c3628ad1e8208eab7c85485b78824e94f8688f4f 100644 (file)
@@ -174,10 +174,15 @@ abstract class AbstractNormalizedNodePruner implements NormalizedNodeStreamWrite
     public void scalarValue(final Object value) throws IOException {
         checkNotSealed();
         if (unknown == 0) {
     public void scalarValue(final Object value) throws IOException {
         checkNotSealed();
         if (unknown == 0) {
-            delegate.scalarValue(value);
+            delegate.scalarValue(translateScalar(stack.peek(), value));
         }
     }
 
         }
     }
 
+    Object translateScalar(final DataSchemaContextNode<?> context, final Object value) throws IOException {
+        // Default is pass-through
+        return value;
+    }
+
     @Override
     public void endNode() throws IOException {
         checkNotSealed();
     @Override
     public void endNode() throws IOException {
         checkNotSealed();
index 1e95766f84901019cb69314555821d1af21be037..751c96f2b65f290429b91487bd3dbada16c71f4d 100644 (file)
@@ -8,10 +8,26 @@
 package org.opendaylight.controller.cluster.datastore.node.utils.transformer;
 
 import com.google.common.annotations.Beta;
 package org.opendaylight.controller.cluster.datastore.node.utils.transformer;
 
 import com.google.common.annotations.Beta;
+import java.io.IOException;
+import java.math.BigInteger;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.Uint16;
+import org.opendaylight.yangtools.yang.common.Uint32;
+import org.opendaylight.yangtools.yang.common.Uint64;
+import org.opendaylight.yangtools.yang.common.Uint8;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode;
 import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
 import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.TypedDataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.type.Uint16TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.Uint32TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.Uint64TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.Uint8TypeDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * The NormalizedNodePruner removes all nodes from the input NormalizedNode that do not have a corresponding
 
 /**
  * The NormalizedNodePruner removes all nodes from the input NormalizedNode that do not have a corresponding
@@ -22,12 +38,62 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
  * through {@link #initializeForPath(YangInstanceIdentifier)}.
  */
 @Beta
  * through {@link #initializeForPath(YangInstanceIdentifier)}.
  */
 @Beta
-public final class ReusableNormalizedNodePruner extends AbstractNormalizedNodePruner {
-    private ReusableNormalizedNodePruner(final SchemaContext schemaContext) {
+public abstract class ReusableNormalizedNodePruner extends AbstractNormalizedNodePruner {
+    private static final class SimplePruner extends ReusableNormalizedNodePruner {
+        SimplePruner(final SchemaContext schemaContext) {
+            super(schemaContext);
+        }
+
+        SimplePruner(final DataSchemaContextTree tree) {
+            super(tree);
+        }
+
+        @Override
+        public ReusableNormalizedNodePruner duplicate() {
+            return new SimplePruner(getTree());
+        }
+    }
+
+    private static final class UintAdaptingPruner extends ReusableNormalizedNodePruner {
+        private static final Logger LOG = LoggerFactory.getLogger(UintAdaptingPruner.class);
+
+        UintAdaptingPruner(final DataSchemaContextTree tree) {
+            super(tree);
+        }
+
+        @Override
+        public ReusableNormalizedNodePruner duplicate() {
+            return new UintAdaptingPruner(getTree());
+        }
+
+        @Override
+        Object translateScalar(final DataSchemaContextNode<?> context, final Object value) throws IOException {
+            final DataSchemaNode schema = context.getDataSchemaNode();
+            if (schema instanceof TypedDataSchemaNode) {
+                final TypeDefinition<?> type = ((TypedDataSchemaNode) schema).getType();
+                if (value instanceof Short && type instanceof Uint8TypeDefinition) {
+                    LOG.trace("Translating legacy uint8 {}", value);
+                    return Uint8.valueOf((Short) value);
+                } else if (value instanceof Integer && type instanceof Uint16TypeDefinition) {
+                    LOG.trace("Translating legacy uint16 {}", value);
+                    return Uint16.valueOf((Integer) value);
+                } else if (value instanceof Long && type instanceof Uint32TypeDefinition) {
+                    LOG.trace("Translating legacy uint32 {}", value);
+                    return Uint32.valueOf((Long) value);
+                } else if (value instanceof BigInteger && type instanceof Uint64TypeDefinition) {
+                    LOG.trace("Translating legacy uint64 {}", value);
+                    return Uint64.valueOf((BigInteger) value);
+                }
+            }
+            return value;
+        }
+    }
+
+    ReusableNormalizedNodePruner(final SchemaContext schemaContext) {
         super(schemaContext);
     }
 
         super(schemaContext);
     }
 
-    private ReusableNormalizedNodePruner(final DataSchemaContextTree tree) {
+    ReusableNormalizedNodePruner(final DataSchemaContextTree tree) {
         super(tree);
     }
 
         super(tree);
     }
 
@@ -39,7 +105,7 @@ public final class ReusableNormalizedNodePruner extends AbstractNormalizedNodePr
      * @throws NullPointerException if {@code schemaContext} is null
      */
     public static @NonNull ReusableNormalizedNodePruner forSchemaContext(final SchemaContext schemaContext) {
      * @throws NullPointerException if {@code schemaContext} is null
      */
     public static @NonNull ReusableNormalizedNodePruner forSchemaContext(final SchemaContext schemaContext) {
-        return new ReusableNormalizedNodePruner(schemaContext);
+        return new SimplePruner(schemaContext);
     }
 
     /**
     }
 
     /**
@@ -51,7 +117,7 @@ public final class ReusableNormalizedNodePruner extends AbstractNormalizedNodePr
      * @throws NullPointerException if {@code schemaContext} is null
      */
     public static @NonNull ReusableNormalizedNodePruner forDataSchemaContext(final DataSchemaContextTree tree) {
      * @throws NullPointerException if {@code schemaContext} is null
      */
     public static @NonNull ReusableNormalizedNodePruner forDataSchemaContext(final DataSchemaContextTree tree) {
-        return new ReusableNormalizedNodePruner(tree);
+        return new SimplePruner(tree);
     }
 
     /**
     }
 
     /**
@@ -61,9 +127,7 @@ public final class ReusableNormalizedNodePruner extends AbstractNormalizedNodePr
      *
      * @return A new uninitialized pruner bound to the same SchemaContext as this one.
      */
      *
      * @return A new uninitialized pruner bound to the same SchemaContext as this one.
      */
-    public @NonNull ReusableNormalizedNodePruner duplicate() {
-        return new ReusableNormalizedNodePruner(getTree());
-    }
+    public abstract @NonNull ReusableNormalizedNodePruner duplicate();
 
     /**
      * Initialize this pruner for processing a node at specified path.
 
     /**
      * Initialize this pruner for processing a node at specified path.
@@ -71,7 +135,11 @@ public final class ReusableNormalizedNodePruner extends AbstractNormalizedNodePr
      * @param path Path that will be processed next
      * @throws NullPointerException if {@code path} is null
      */
      * @param path Path that will be processed next
      * @throws NullPointerException if {@code path} is null
      */
-    public void initializeForPath(final YangInstanceIdentifier path) {
+    public final void initializeForPath(final YangInstanceIdentifier path) {
         initialize(path);
     }
         initialize(path);
     }
+
+    public final @NonNull ReusableNormalizedNodePruner withUintAdaption() {
+        return new UintAdaptingPruner(getTree());
+    }
 }
 }