BUG-5280: move DataTreeCandidate serialization to its own class 67/39267/32
authorRobert Varga <rovarga@cisco.com>
Mon, 23 May 2016 14:44:35 +0000 (16:44 +0200)
committerTom Pantelis <tpanteli@brocade.com>
Fri, 10 Jun 2016 11:38:27 +0000 (11:38 +0000)
This is a useful utility, which can be reused across multiple objects.
Split it out into its own class.

Change-Id: Ib21abf0ae42e3f70f44b3214039c0f26464bbc3e
Signed-off-by: Robert Varga <rovarga@cisco.com>
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataTreeCandidatePayload.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/AbstractDataTreeCandidateNode.java [moved from opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/AbstractDataTreeCandidateNode.java with 97% similarity]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/DataTreeCandidateInputOutput.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/DeletedDataTreeCandidateNode.java [moved from opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DeletedDataTreeCandidateNode.java with 96% similarity]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/ModifiedDataTreeCandidateNode.java [moved from opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ModifiedDataTreeCandidateNode.java with 97% similarity]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/package-info.java [new file with mode: 0644]

index 21083618f04f26605a809f68c4277378c64df8f4..8da70c2e29cc8a7c5019873e19dfe55ab9ea4f04 100644 (file)
@@ -8,40 +8,21 @@
 package org.opendaylight.controller.cluster.datastore;
 
 import com.google.common.base.Preconditions;
-import com.google.common.io.ByteArrayDataInput;
 import com.google.common.io.ByteArrayDataOutput;
 import com.google.common.io.ByteStreams;
 import java.io.Externalizable;
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeDataInput;
-import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeDataOutput;
-import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeInputStreamReader;
-import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeInputOutput;
+import org.opendaylight.controller.cluster.datastore.persisted.DataTreeCandidateInputOutput;
 import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNodes;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidates;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 final class DataTreeCandidatePayload extends Payload implements Externalizable {
     private static final Logger LOG = LoggerFactory.getLogger(DataTreeCandidatePayload.class);
     private static final long serialVersionUID = 1L;
-    private static final byte DELETE = 0;
-    private static final byte SUBTREE_MODIFIED = 1;
-    private static final byte UNMODIFIED = 2;
-    private static final byte WRITE = 3;
-    private static final byte APPEARED = 4;
-    private static final byte DISAPPEARED = 5;
 
     private transient byte[] serialized;
 
@@ -53,81 +34,10 @@ final class DataTreeCandidatePayload extends Payload implements Externalizable {
         this.serialized = Preconditions.checkNotNull(serialized);
     }
 
-    private static void writeChildren(final NormalizedNodeDataOutput out,
-            final Collection<DataTreeCandidateNode> children) throws IOException {
-        out.writeInt(children.size());
-        for (DataTreeCandidateNode child : children) {
-            writeNode(out, child);
-        }
-    }
-
-    private static void writeNode(final NormalizedNodeDataOutput out, final DataTreeCandidateNode node)
-            throws IOException {
-        switch (node.getModificationType()) {
-        case APPEARED:
-            out.writeByte(APPEARED);
-            out.writePathArgument(node.getIdentifier());
-            writeChildren(out, node.getChildNodes());
-            break;
-        case DELETE:
-            out.writeByte(DELETE);
-            out.writePathArgument(node.getIdentifier());
-            break;
-        case DISAPPEARED:
-            out.writeByte(DISAPPEARED);
-            out.writePathArgument(node.getIdentifier());
-            writeChildren(out, node.getChildNodes());
-            break;
-        case SUBTREE_MODIFIED:
-            out.writeByte(SUBTREE_MODIFIED);
-            out.writePathArgument(node.getIdentifier());
-            writeChildren(out, node.getChildNodes());
-            break;
-        case WRITE:
-            out.writeByte(WRITE);
-            out.writeNormalizedNode(node.getDataAfter().get());
-            break;
-        case UNMODIFIED:
-            out.writeByte(UNMODIFIED);
-            break;
-        default:
-            throw new IllegalArgumentException("Unhandled node type " + node.getModificationType());
-        }
-    }
-
     static DataTreeCandidatePayload create(final DataTreeCandidate candidate) {
         final ByteArrayDataOutput out = ByteStreams.newDataOutput();
-        try (final NormalizedNodeDataOutput writer = NormalizedNodeInputOutput.newDataOutput(out)) {
-            writer.writeYangInstanceIdentifier(candidate.getRootPath());
-
-            final DataTreeCandidateNode node = candidate.getRootNode();
-            switch (node.getModificationType()) {
-            case APPEARED:
-                writer.writeByte(APPEARED);
-                writeChildren(writer, node.getChildNodes());
-                break;
-            case DELETE:
-                writer.writeByte(DELETE);
-                break;
-            case DISAPPEARED:
-                writer.writeByte(DISAPPEARED);
-                writeChildren(writer, node.getChildNodes());
-                break;
-            case SUBTREE_MODIFIED:
-                writer.writeByte(SUBTREE_MODIFIED);
-                writeChildren(writer, node.getChildNodes());
-                break;
-            case UNMODIFIED:
-                writer.writeByte(UNMODIFIED);
-                break;
-            case WRITE:
-                writer.writeByte(WRITE);
-                writer.writeNormalizedNode(node.getDataAfter().get());
-                break;
-            default:
-                throw new IllegalArgumentException("Unhandled node type " + node.getModificationType());
-            }
-
+        try {
+            DataTreeCandidateInputOutput.writeDataTreeCandidate(out, candidate);
         } catch (IOException e) {
             throw new IllegalArgumentException(String.format("Failed to serialize candidate %s", candidate), e);
         }
@@ -135,80 +45,9 @@ final class DataTreeCandidatePayload extends Payload implements Externalizable {
         return new DataTreeCandidatePayload(out.toByteArray());
     }
 
-    private static Collection<DataTreeCandidateNode> readChildren(final NormalizedNodeDataInput in) throws IOException {
-        final int size = in.readInt();
-        if (size != 0) {
-            final Collection<DataTreeCandidateNode> ret = new ArrayList<>(size);
-            for (int i = 0; i < size; ++i) {
-                final DataTreeCandidateNode child = readNode(in);
-                if (child != null) {
-                    ret.add(child);
-                }
-            }
-            return ret;
-        } else {
-            return Collections.emptyList();
-        }
-    }
-
-    private static DataTreeCandidateNode readModifiedNode(final ModificationType type,
-            final NormalizedNodeDataInput in) throws IOException {
-
-        final PathArgument identifier = in.readPathArgument();
-        final Collection<DataTreeCandidateNode> children = readChildren(in);
-        if (children.isEmpty()) {
-            LOG.debug("Modified node {} does not have any children, not instantiating it", identifier);
-            return null;
-        } else {
-            return ModifiedDataTreeCandidateNode.create(identifier, type, children);
-        }
-    }
-
-    private static DataTreeCandidateNode readNode(final NormalizedNodeDataInput in) throws IOException {
-        final byte type = in.readByte();
-        switch (type) {
-        case APPEARED:
-            return readModifiedNode(ModificationType.APPEARED, in);
-        case DELETE:
-            return DeletedDataTreeCandidateNode.create(in.readPathArgument());
-        case DISAPPEARED:
-            return readModifiedNode(ModificationType.DISAPPEARED, in);
-        case SUBTREE_MODIFIED:
-            return readModifiedNode(ModificationType.SUBTREE_MODIFIED, in);
-        case UNMODIFIED:
-            return null;
-        case WRITE:
-            return DataTreeCandidateNodes.fromNormalizedNode(in.readNormalizedNode());
-        default:
-            throw new IllegalArgumentException("Unhandled node type " + type);
-        }
-    }
-
-    private static DataTreeCandidate parseCandidate(final ByteArrayDataInput in) throws IOException {
-        final NormalizedNodeDataInput reader = new NormalizedNodeInputStreamReader(in);
-        final YangInstanceIdentifier rootPath = reader.readYangInstanceIdentifier();
-        final byte type = reader.readByte();
-
-        final DataTreeCandidateNode rootNode;
-        switch (type) {
-        case DELETE:
-            rootNode = DeletedDataTreeCandidateNode.create();
-            break;
-        case SUBTREE_MODIFIED:
-            rootNode = ModifiedDataTreeCandidateNode.create(readChildren(reader));
-            break;
-        case WRITE:
-            rootNode = DataTreeCandidateNodes.fromNormalizedNode(reader.readNormalizedNode());
-            break;
-        default:
-            throw new IllegalArgumentException("Unhandled node type " + type);
-        }
-
-        return DataTreeCandidates.newDataTreeCandidate(rootPath, rootNode);
-    }
 
     DataTreeCandidate getCandidate() throws IOException {
-        return parseCandidate(ByteStreams.newDataInput(serialized));
+        return DataTreeCandidateInputOutput.readDataTreeCandidate(ByteStreams.newDataInput(serialized));
     }
 
     @Override
@@ -217,14 +56,14 @@ final class DataTreeCandidatePayload extends Payload implements Externalizable {
     }
 
     @Override
-    public void writeExternal(ObjectOutput out) throws IOException {
+    public void writeExternal(final ObjectOutput out) throws IOException {
         out.writeByte((byte)serialVersionUID);
         out.writeInt(serialized.length);
         out.write(serialized);
     }
 
     @Override
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+    public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
         final long version = in.readByte();
         Preconditions.checkArgument(version == serialVersionUID, "Unsupported serialization version %s", version);
 
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/DataTreeCandidateInputOutput.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/DataTreeCandidateInputOutput.java
new file mode 100644 (file)
index 0000000..9d0153f
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.cluster.datastore.persisted;
+
+import com.google.common.annotations.Beta;
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeDataInput;
+import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeDataOutput;
+import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeInputOutput;
+import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeInputStreamReader;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNodes;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidates;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Utility serialization/deserialization for {@link DataTreeCandidate}. Note that this utility does not maintain
+ * before-image information across serialization.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public final class DataTreeCandidateInputOutput {
+    private static final Logger LOG = LoggerFactory.getLogger(DataTreeCandidateInputOutput.class);
+    private static final byte DELETE = 0;
+    private static final byte SUBTREE_MODIFIED = 1;
+    private static final byte UNMODIFIED = 2;
+    private static final byte WRITE = 3;
+    private static final byte APPEARED = 4;
+    private static final byte DISAPPEARED = 5;
+
+    private DataTreeCandidateInputOutput() {
+        throw new UnsupportedOperationException();
+    }
+
+    private static DataTreeCandidateNode readModifiedNode(final ModificationType type,
+            final NormalizedNodeDataInput in) throws IOException {
+
+        final PathArgument identifier = in.readPathArgument();
+        final Collection<DataTreeCandidateNode> children = readChildren(in);
+        if (children.isEmpty()) {
+            LOG.debug("Modified node {} does not have any children, not instantiating it", identifier);
+            return null;
+        } else {
+            return ModifiedDataTreeCandidateNode.create(identifier, type, children);
+        }
+    }
+
+    private static Collection<DataTreeCandidateNode> readChildren(final NormalizedNodeDataInput in) throws IOException {
+        final int size = in.readInt();
+        if (size != 0) {
+            final Collection<DataTreeCandidateNode> ret = new ArrayList<>(size);
+            for (int i = 0; i < size; ++i) {
+                final DataTreeCandidateNode child = readNode(in);
+                if (child != null) {
+                    ret.add(child);
+                }
+            }
+            return ret;
+        } else {
+            return Collections.emptyList();
+        }
+    }
+
+    private static DataTreeCandidateNode readNode(final NormalizedNodeDataInput in) throws IOException {
+        final byte type = in.readByte();
+        switch (type) {
+        case APPEARED:
+            return readModifiedNode(ModificationType.APPEARED, in);
+        case DELETE:
+            return DeletedDataTreeCandidateNode.create(in.readPathArgument());
+        case DISAPPEARED:
+            return readModifiedNode(ModificationType.DISAPPEARED, in);
+        case SUBTREE_MODIFIED:
+            return readModifiedNode(ModificationType.SUBTREE_MODIFIED, in);
+        case UNMODIFIED:
+            return null;
+        case WRITE:
+            return DataTreeCandidateNodes.fromNormalizedNode(in.readNormalizedNode());
+        default:
+            throw new IllegalArgumentException("Unhandled node type " + type);
+        }
+    }
+
+    public static DataTreeCandidate readDataTreeCandidate(final DataInput in) throws IOException {
+        final NormalizedNodeDataInput reader = new NormalizedNodeInputStreamReader(in);
+        final YangInstanceIdentifier rootPath = reader.readYangInstanceIdentifier();
+        final byte type = reader.readByte();
+
+        final DataTreeCandidateNode rootNode;
+        switch (type) {
+        case DELETE:
+            rootNode = DeletedDataTreeCandidateNode.create();
+            break;
+        case SUBTREE_MODIFIED:
+            rootNode = ModifiedDataTreeCandidateNode.create(readChildren(reader));
+            break;
+        case WRITE:
+            rootNode = DataTreeCandidateNodes.fromNormalizedNode(reader.readNormalizedNode());
+            break;
+        default:
+            throw new IllegalArgumentException("Unhandled node type " + type);
+        }
+
+        return DataTreeCandidates.newDataTreeCandidate(rootPath, rootNode);
+    }
+
+
+    private static void writeChildren(final NormalizedNodeDataOutput out,
+            final Collection<DataTreeCandidateNode> children) throws IOException {
+        out.writeInt(children.size());
+        for (DataTreeCandidateNode child : children) {
+            writeNode(out, child);
+        }
+    }
+
+    private static void writeNode(final NormalizedNodeDataOutput out, final DataTreeCandidateNode node)
+            throws IOException {
+        switch (node.getModificationType()) {
+        case APPEARED:
+            out.writeByte(APPEARED);
+            out.writePathArgument(node.getIdentifier());
+            writeChildren(out, node.getChildNodes());
+            break;
+        case DELETE:
+            out.writeByte(DELETE);
+            out.writePathArgument(node.getIdentifier());
+            break;
+        case DISAPPEARED:
+            out.writeByte(DISAPPEARED);
+            out.writePathArgument(node.getIdentifier());
+            writeChildren(out, node.getChildNodes());
+            break;
+        case SUBTREE_MODIFIED:
+            out.writeByte(SUBTREE_MODIFIED);
+            out.writePathArgument(node.getIdentifier());
+            writeChildren(out, node.getChildNodes());
+            break;
+        case WRITE:
+            out.writeByte(WRITE);
+            out.writeNormalizedNode(node.getDataAfter().get());
+            break;
+        case UNMODIFIED:
+            out.writeByte(UNMODIFIED);
+            break;
+        default:
+            throw new IllegalArgumentException("Unhandled node type " + node.getModificationType());
+        }
+    }
+
+    public static void writeDataTreeCandidate(final DataOutput out, DataTreeCandidate candidate) throws IOException {
+        try (final NormalizedNodeDataOutput writer = NormalizedNodeInputOutput.newDataOutput(out)) {
+            writer.writeYangInstanceIdentifier(candidate.getRootPath());
+
+            final DataTreeCandidateNode node = candidate.getRootNode();
+            switch (node.getModificationType()) {
+            case APPEARED:
+                writer.writeByte(APPEARED);
+                writeChildren(writer, node.getChildNodes());
+                break;
+            case DELETE:
+                writer.writeByte(DELETE);
+                break;
+            case DISAPPEARED:
+                writer.writeByte(DISAPPEARED);
+                writeChildren(writer, node.getChildNodes());
+                break;
+            case SUBTREE_MODIFIED:
+                writer.writeByte(SUBTREE_MODIFIED);
+                writeChildren(writer, node.getChildNodes());
+                break;
+            case UNMODIFIED:
+                writer.writeByte(UNMODIFIED);
+                break;
+            case WRITE:
+                writer.writeByte(WRITE);
+                writer.writeNormalizedNode(node.getDataAfter().get());
+                break;
+            default:
+                throw new IllegalArgumentException("Unhandled node type " + node.getModificationType());
+            }
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/package-info.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/package-info.java
new file mode 100644 (file)
index 0000000..f3905b9
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+/**
+ * Persisted backend structures. This includes various Payloads and Snapshots.
+ *
+ * @author Robert Varga
+ */
+package org.opendaylight.controller.cluster.datastore.persisted;
\ No newline at end of file