Bug 7521: Convert byte[] to ShardManagerSnapshot in DatastoreSnapshot 06/51006/7
authorTom Pantelis <tpanteli@brocade.com>
Wed, 25 Jan 2017 13:04:57 +0000 (08:04 -0500)
committerTom Pantelis <tpanteli@brocade.com>
Fri, 17 Feb 2017 14:50:44 +0000 (09:50 -0500)
Created a new ShardManagerSnapshot class in the persisted package
which is now stored in the DatastoreSnapshot in lieu of a
serialized byte[]. The previous ShardManagerSnapshot class was
deprecated and readResolves to the new class.

Change-Id: I1ae363e9711cf3bef6b6dd6257fa56bd41465bf3
Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
12 files changed:
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ShardManagerSnapshot.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/DatastoreSnapshotList.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/DatastoreSnapshot.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/ShardManagerSnapshot.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManager.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManagerGetSnapshotReplyActor.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManagerSnapshot.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DatastoreSnapshotRestoreTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/messages/DatastoreSnapshotListTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/persisted/ShardManagerSnapshotTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManagerGetSnapshotReplyActorTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManagerTest.java

index eb8c139903a3a21ec0c273d3ac39b779f887a9e7..994f0761b09118f8c1a8164f5d4b07c872d0554c 100644 (file)
@@ -40,6 +40,6 @@ public class ShardManagerSnapshot implements Serializable {
     }
 
     private Object readResolve() throws ObjectStreamException {
     }
 
     private Object readResolve() throws ObjectStreamException {
-        return org.opendaylight.controller.cluster.datastore.shardmanager.ShardManagerSnapshot.forShardList(shardList);
+        return new org.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot(shardList);
     }
 }
     }
 }
index 8400e0c3e236fb2eaf6f8be67932c48b01e1064e..42f3129728aae62f9a34527c1888c10a21501de2 100644 (file)
@@ -13,6 +13,7 @@ import java.io.ObjectInputStream;
 import java.util.ArrayList;
 import java.util.List;
 import org.opendaylight.controller.cluster.datastore.persisted.ShardDataTreeSnapshot;
 import java.util.ArrayList;
 import java.util.List;
 import org.opendaylight.controller.cluster.datastore.persisted.ShardDataTreeSnapshot;
+import org.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot;
 import org.opendaylight.controller.cluster.datastore.persisted.ShardSnapshotState;
 import org.opendaylight.controller.cluster.raft.Snapshot;
 import org.opendaylight.controller.cluster.raft.persisted.EmptyState;
 import org.opendaylight.controller.cluster.datastore.persisted.ShardSnapshotState;
 import org.opendaylight.controller.cluster.raft.Snapshot;
 import org.opendaylight.controller.cluster.raft.persisted.EmptyState;
@@ -38,25 +39,37 @@ public class DatastoreSnapshotList extends ArrayList<DatastoreSnapshot> {
                 new ArrayList<>(size());
         for (DatastoreSnapshot legacy: this) {
             snapshots.add(new org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot(
                 new ArrayList<>(size());
         for (DatastoreSnapshot legacy: this) {
             snapshots.add(new org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot(
-                    legacy.getType(), legacy.getShardManagerSnapshot(), fromLegacy(legacy.getShardSnapshots())));
+                    legacy.getType(), deserializeShardManagerSnapshot(legacy.getShardManagerSnapshot()),
+                    fromLegacy(legacy.getShardSnapshots())));
         }
 
         return new org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshotList(snapshots);
     }
 
         }
 
         return new org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshotList(snapshots);
     }
 
+    private static org.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot
+            deserializeShardManagerSnapshot(byte [] bytes) throws IOException, ClassNotFoundException {
+        if (bytes == null) {
+            return null;
+        }
+
+        try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes))) {
+            return (ShardManagerSnapshot) ois.readObject();
+        }
+    }
+
     private static List<org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot.ShardSnapshot>
             fromLegacy(List<DatastoreSnapshot.ShardSnapshot> from) throws IOException, ClassNotFoundException {
         List<org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot.ShardSnapshot> snapshots =
                 new ArrayList<>(from.size());
         for (DatastoreSnapshot.ShardSnapshot legacy: from) {
             snapshots.add(new org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot.ShardSnapshot(
     private static List<org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot.ShardSnapshot>
             fromLegacy(List<DatastoreSnapshot.ShardSnapshot> from) throws IOException, ClassNotFoundException {
         List<org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot.ShardSnapshot> snapshots =
                 new ArrayList<>(from.size());
         for (DatastoreSnapshot.ShardSnapshot legacy: from) {
             snapshots.add(new org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot.ShardSnapshot(
-                    legacy.getName(), deserialize(legacy.getSnapshot())));
+                    legacy.getName(), deserializeShardSnapshot(legacy.getSnapshot())));
         }
 
         return snapshots;
     }
 
         }
 
         return snapshots;
     }
 
-    private static org.opendaylight.controller.cluster.raft.persisted.Snapshot deserialize(byte[] bytes)
+    private static org.opendaylight.controller.cluster.raft.persisted.Snapshot deserializeShardSnapshot(byte[] bytes)
             throws IOException, ClassNotFoundException {
         try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes))) {
             Snapshot legacy = (Snapshot) ois.readObject();
             throws IOException, ClassNotFoundException {
         try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes))) {
             Snapshot legacy = (Snapshot) ois.readObject();
index 9eb8a066d554da35cfff472b64a2773d12f5d759..fec44082ecdfee199f532dbf9bdee0be1d2c285c 100644 (file)
@@ -9,7 +9,6 @@ package org.opendaylight.controller.cluster.datastore.persisted;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.io.Externalizable;
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.Externalizable;
 import java.io.IOException;
 import java.io.ObjectInput;
@@ -59,7 +58,7 @@ public class DatastoreSnapshot implements Serializable {
         @Override
         public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
             String type = (String)in.readObject();
         @Override
         public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
             String type = (String)in.readObject();
-            byte[] shardManagerSnapshot = (byte[]) in.readObject();
+            ShardManagerSnapshot shardManagerSnapshot = (ShardManagerSnapshot) in.readObject();
 
             int size = in.readInt();
             List<ShardSnapshot> shardSnapshots = new ArrayList<>(size);
 
             int size = in.readInt();
             List<ShardSnapshot> shardSnapshots = new ArrayList<>(size);
@@ -76,13 +75,10 @@ public class DatastoreSnapshot implements Serializable {
     }
 
     private final String type;
     }
 
     private final String type;
-    private final byte[] shardManagerSnapshot;
+    private final ShardManagerSnapshot shardManagerSnapshot;
     private final List<ShardSnapshot> shardSnapshots;
 
     private final List<ShardSnapshot> shardSnapshots;
 
-    @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "Stores a reference to an externally mutable byte[] "
-            + "object but this is OK since this class is merely a DTO and does not process byte[] internally. "
-            + "Also it would be inefficient to create a return copy as the byte[] could be large.")
-    public DatastoreSnapshot(@Nonnull String type, @Nullable byte[] shardManagerSnapshot,
+    public DatastoreSnapshot(@Nonnull String type, @Nullable ShardManagerSnapshot shardManagerSnapshot,
             @Nonnull List<ShardSnapshot> shardSnapshots) {
         this.type = Preconditions.checkNotNull(type);
         this.shardManagerSnapshot = shardManagerSnapshot;
             @Nonnull List<ShardSnapshot> shardSnapshots) {
         this.type = Preconditions.checkNotNull(type);
         this.shardManagerSnapshot = shardManagerSnapshot;
@@ -94,11 +90,8 @@ public class DatastoreSnapshot implements Serializable {
         return type;
     }
 
         return type;
     }
 
-    @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "Exposes a mutable object stored in a field but "
-            + "this is OK since this class is merely a DTO and does not process byte[] internally. "
-            + "Also it would be inefficient to create a return copy as the byte[] could be large.")
     @Nullable
     @Nullable
-    public byte[] getShardManagerSnapshot() {
+    public ShardManagerSnapshot getShardManagerSnapshot() {
         return shardManagerSnapshot;
     }
 
         return shardManagerSnapshot;
     }
 
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/ShardManagerSnapshot.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/ShardManagerSnapshot.java
new file mode 100644 (file)
index 0000000..6bb6ea8
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2017 Brocade Communications 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.collect.ImmutableList;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.Nonnull;
+
+/**
+ * Represents the persisted snapshot state for the ShardManager.
+ *
+ * @author Thomas Pantelis
+ */
+public class ShardManagerSnapshot implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private static final class Proxy implements Externalizable {
+        private static final long serialVersionUID = 1L;
+
+        private ShardManagerSnapshot snapshot;
+
+        // checkstyle flags the public modifier as redundant which really doesn't make sense since it clearly isn't
+        // redundant. It is explicitly needed for Java serialization to be able to create instances via reflection.
+        @SuppressWarnings("checkstyle:RedundantModifier")
+        public Proxy() {
+            // For Externalizable
+        }
+
+        Proxy(final ShardManagerSnapshot snapshot) {
+            this.snapshot = snapshot;
+        }
+
+        @Override
+        public void writeExternal(ObjectOutput out) throws IOException {
+            out.writeInt(snapshot.shardList.size());
+            for (String shard: snapshot.shardList) {
+                out.writeObject(shard);
+            }
+        }
+
+        @Override
+        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+            int size = in.readInt();
+            List<String> shardList = new ArrayList<>(size);
+            for (int i = 0; i < size; i++) {
+                shardList.add((String) in.readObject());
+            }
+
+            snapshot = new ShardManagerSnapshot(shardList);
+        }
+
+        private Object readResolve() {
+            return snapshot;
+        }
+    }
+
+    private final List<String> shardList;
+
+    public ShardManagerSnapshot(@Nonnull final List<String> shardList) {
+        this.shardList = ImmutableList.copyOf(shardList);
+    }
+
+    public List<String> getShardList() {
+        return this.shardList;
+    }
+
+    @SuppressWarnings("static-method")
+    private Object writeReplace() {
+        return new Proxy(this);
+    }
+
+    @Override
+    public String toString() {
+        return "ShardManagerSnapshot [ShardList = " + shardList + " ]";
+    }
+}
index 736742cb1c73e49d15760fbbb99098d4bd99619b..b2c9d30184079141e552c21edfafcf8ba8ba2c0b 100644 (file)
@@ -33,9 +33,6 @@ import akka.persistence.SnapshotSelectionCriteria;
 import akka.util.Timeout;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 import akka.util.Timeout;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -50,7 +47,6 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
 import java.util.concurrent.TimeoutException;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
-import org.apache.commons.lang3.SerializationUtils;
 import org.opendaylight.controller.cluster.access.concepts.MemberName;
 import org.opendaylight.controller.cluster.common.actor.AbstractUntypedPersistentActorWithMetering;
 import org.opendaylight.controller.cluster.datastore.ClusterWrapper;
 import org.opendaylight.controller.cluster.access.concepts.MemberName;
 import org.opendaylight.controller.cluster.common.actor.AbstractUntypedPersistentActorWithMetering;
 import org.opendaylight.controller.cluster.datastore.ClusterWrapper;
@@ -84,6 +80,7 @@ import org.opendaylight.controller.cluster.datastore.messages.RemoveShardReplica
 import org.opendaylight.controller.cluster.datastore.messages.ShardLeaderStateChanged;
 import org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext;
 import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot;
 import org.opendaylight.controller.cluster.datastore.messages.ShardLeaderStateChanged;
 import org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext;
 import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot;
+import org.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot;
 import org.opendaylight.controller.cluster.datastore.utils.ClusterUtils;
 import org.opendaylight.controller.cluster.datastore.utils.Dispatchers;
 import org.opendaylight.controller.cluster.datastore.utils.PrimaryShardInfoFutureCache;
 import org.opendaylight.controller.cluster.datastore.utils.ClusterUtils;
 import org.opendaylight.controller.cluster.datastore.utils.Dispatchers;
 import org.opendaylight.controller.cluster.datastore.utils.PrimaryShardInfoFutureCache;
@@ -412,13 +409,8 @@ class ShardManager extends AbstractUntypedPersistentActorWithMetering {
             return;
         }
 
             return;
         }
 
-        byte[] shardManagerSnapshot = null;
-        if (currentSnapshot != null) {
-            shardManagerSnapshot = SerializationUtils.serialize(currentSnapshot);
-        }
-
         ActorRef replyActor = getContext().actorOf(ShardManagerGetSnapshotReplyActor.props(
         ActorRef replyActor = getContext().actorOf(ShardManagerGetSnapshotReplyActor.props(
-                new ArrayList<>(localShards.keySet()), type, shardManagerSnapshot , getSender(), persistenceId(),
+                new ArrayList<>(localShards.keySet()), type, currentSnapshot , getSender(), persistenceId(),
                 datastoreContextFactory.getBaseDatastoreContext().getShardInitializationTimeout().duration()));
 
         for (ShardInformation shardInfo: localShards.values()) {
                 datastoreContextFactory.getBaseDatastoreContext().getShardInitializationTimeout().duration()));
 
         for (ShardInformation shardInfo: localShards.values()) {
@@ -724,16 +716,11 @@ class ShardManager extends AbstractUntypedPersistentActorWithMetering {
 
         if (currentSnapshot == null && restoreFromSnapshot != null
                 && restoreFromSnapshot.getShardManagerSnapshot() != null) {
 
         if (currentSnapshot == null && restoreFromSnapshot != null
                 && restoreFromSnapshot.getShardManagerSnapshot() != null) {
-            try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
-                    restoreFromSnapshot.getShardManagerSnapshot()))) {
-                ShardManagerSnapshot snapshot = (ShardManagerSnapshot) ois.readObject();
+            ShardManagerSnapshot snapshot = restoreFromSnapshot.getShardManagerSnapshot();
 
 
-                LOG.debug("{}: Deserialized restored ShardManagerSnapshot: {}", persistenceId(), snapshot);
+            LOG.debug("{}: Restoring from ShardManagerSnapshot: {}", persistenceId(), snapshot);
 
 
-                applyShardManagerSnapshot(snapshot);
-            } catch (ClassNotFoundException | IOException e) {
-                LOG.error("{}: Error deserializing restored ShardManagerSnapshot", persistenceId(), e);
-            }
+            applyShardManagerSnapshot(snapshot);
         }
 
         createLocalShards();
         }
 
         createLocalShards();
index d64b1086dde359719ffadd03acf910dabb39487c..c474cf89fc8ee6cf8f35f91b43189a13d332824c 100644 (file)
@@ -22,6 +22,7 @@ import java.util.concurrent.TimeoutException;
 import org.opendaylight.controller.cluster.datastore.identifiers.ShardIdentifier;
 import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot;
 import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot.ShardSnapshot;
 import org.opendaylight.controller.cluster.datastore.identifiers.ShardIdentifier;
 import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot;
 import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot.ShardSnapshot;
+import org.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot;
 import org.opendaylight.controller.cluster.raft.client.messages.GetSnapshotReply;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.opendaylight.controller.cluster.raft.client.messages.GetSnapshotReply;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -86,8 +87,8 @@ class ShardManagerGetSnapshotReplyActor extends UntypedActor {
         }
     }
 
         }
     }
 
-    public static Props props(Collection<String> shardNames, String datastoreType, byte[] shardManagerSnapshot,
-            ActorRef replyToActor, String id, Duration receiveTimeout) {
+    public static Props props(Collection<String> shardNames, String datastoreType,
+            ShardManagerSnapshot shardManagerSnapshot, ActorRef replyToActor, String id, Duration receiveTimeout) {
         return Props.create(ShardManagerGetSnapshotReplyActor.class, new Params(shardNames, datastoreType,
                 shardManagerSnapshot, replyToActor, id, receiveTimeout));
     }
         return Props.create(ShardManagerGetSnapshotReplyActor.class, new Params(shardNames, datastoreType,
                 shardManagerSnapshot, replyToActor, id, receiveTimeout));
     }
@@ -95,13 +96,13 @@ class ShardManagerGetSnapshotReplyActor extends UntypedActor {
     private static final class Params {
         final Collection<String> shardNames;
         final String datastoreType;
     private static final class Params {
         final Collection<String> shardNames;
         final String datastoreType;
-        final byte[] shardManagerSnapshot;
+        final ShardManagerSnapshot shardManagerSnapshot;
         final ActorRef replyToActor;
         final String id;
         final Duration receiveTimeout;
 
         final ActorRef replyToActor;
         final String id;
         final Duration receiveTimeout;
 
-        Params(Collection<String> shardNames, String datastoreType, byte[] shardManagerSnapshot, ActorRef replyToActor,
-                String id, Duration receiveTimeout) {
+        Params(Collection<String> shardNames, String datastoreType, ShardManagerSnapshot shardManagerSnapshot,
+                ActorRef replyToActor, String id, Duration receiveTimeout) {
             this.shardNames = shardNames;
             this.datastoreType = datastoreType;
             this.shardManagerSnapshot = shardManagerSnapshot;
             this.shardNames = shardNames;
             this.datastoreType = datastoreType;
             this.shardManagerSnapshot = shardManagerSnapshot;
index d784996bac98489d582ee30b942c288ea9d6d1b9..46fccc745dff7e19560ab083f1126d9b11b2d641 100644 (file)
@@ -15,13 +15,15 @@ import javax.annotation.Nonnull;
 
 /**
  * Persisted data of the ShardManager.
 
 /**
  * Persisted data of the ShardManager.
+ *
+ * @deprecated Use {@link org.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot} instead.
  */
  */
-// FIXME: make this package-protected once forShardList is removed.
+@Deprecated
 public final class ShardManagerSnapshot implements Serializable {
     private static final long serialVersionUID = 1L;
     private final List<String> shardList;
 
 public final class ShardManagerSnapshot implements Serializable {
     private static final long serialVersionUID = 1L;
     private final List<String> shardList;
 
-    ShardManagerSnapshot(final @Nonnull List<String> shardList) {
+    ShardManagerSnapshot(@Nonnull final List<String> shardList) {
         this.shardList = ImmutableList.copyOf(shardList);
     }
 
         this.shardList = ImmutableList.copyOf(shardList);
     }
 
@@ -40,6 +42,10 @@ public final class ShardManagerSnapshot implements Serializable {
         return new ShardManagerSnapshot(shardList);
     }
 
         return new ShardManagerSnapshot(shardList);
     }
 
+    private Object readResolve() {
+        return new org.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot(shardList);
+    }
+
     @Override
     public String toString() {
         return "ShardManagerSnapshot [ShardList = " + shardList + " ]";
     @Override
     public String toString() {
         return "ShardManagerSnapshot [ShardList = " + shardList + " ]";
index bbbd95fd08ad777f3462bed408f66d994d4ec773..67af9bb3487ff3ca31f886eacfee98e7d87c483c 100644 (file)
@@ -18,15 +18,14 @@ import java.io.FileOutputStream;
 import java.math.BigInteger;
 import java.util.Arrays;
 import java.util.Collections;
 import java.math.BigInteger;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.Objects;
 import org.apache.commons.lang3.SerializationUtils;
 import org.junit.After;
 import org.junit.Test;
 import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot;
 import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshotList;
 import org.opendaylight.controller.cluster.datastore.persisted.MetadataShardDataTreeSnapshot;
 import org.apache.commons.lang3.SerializationUtils;
 import org.junit.After;
 import org.junit.Test;
 import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot;
 import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshotList;
 import org.opendaylight.controller.cluster.datastore.persisted.MetadataShardDataTreeSnapshot;
+import org.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot;
 import org.opendaylight.controller.cluster.datastore.persisted.ShardSnapshotState;
 import org.opendaylight.controller.cluster.datastore.persisted.ShardSnapshotState;
-import org.opendaylight.controller.cluster.datastore.shardmanager.ShardManagerSnapshot;
 import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
 import org.opendaylight.controller.cluster.raft.persisted.Snapshot;
 import org.opendaylight.controller.md.cluster.datastore.model.CarsModel;
 import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
 import org.opendaylight.controller.cluster.raft.persisted.Snapshot;
 import org.opendaylight.controller.md.cluster.datastore.model.CarsModel;
@@ -62,7 +61,7 @@ public class DatastoreSnapshotRestoreTest {
         assertTrue("Failed to mkdir " + restoreDirectoryPath, restoreDirectoryFile.mkdirs());
 
         final DatastoreSnapshot configSnapshot = new DatastoreSnapshot("config",
         assertTrue("Failed to mkdir " + restoreDirectoryPath, restoreDirectoryFile.mkdirs());
 
         final DatastoreSnapshot configSnapshot = new DatastoreSnapshot("config",
-                SerializationUtils.serialize(newShardManagerSnapshot("config-one", "config-two")),
+                newShardManagerSnapshot("config-one", "config-two"),
                 Arrays.asList(new DatastoreSnapshot.ShardSnapshot("config-one", newSnapshot(CarsModel.BASE_PATH,
                         CarsModel.newCarsNode(CarsModel.newCarsMapNode(CarsModel.newCarEntry("optima",
                             BigInteger.valueOf(20000L)),CarsModel.newCarEntry("sportage",
                 Arrays.asList(new DatastoreSnapshot.ShardSnapshot("config-one", newSnapshot(CarsModel.BASE_PATH,
                         CarsModel.newCarsNode(CarsModel.newCarsMapNode(CarsModel.newCarEntry("optima",
                             BigInteger.valueOf(20000L)),CarsModel.newCarEntry("sportage",
@@ -97,8 +96,14 @@ public class DatastoreSnapshotRestoreTest {
     private static void assertDatastoreSnapshotEquals(DatastoreSnapshot expected, DatastoreSnapshot actual) {
         assertNotNull("DatastoreSnapshot is null", actual);
         assertEquals("getType", expected.getType(), actual.getType());
     private static void assertDatastoreSnapshotEquals(DatastoreSnapshot expected, DatastoreSnapshot actual) {
         assertNotNull("DatastoreSnapshot is null", actual);
         assertEquals("getType", expected.getType(), actual.getType());
-        assertTrue("ShardManager snapshots don't match", Objects.deepEquals(expected.getShardManagerSnapshot(),
-                actual.getShardManagerSnapshot()));
+
+        if (expected.getShardManagerSnapshot() == null) {
+            assertNull("Expected null ShardManagerSnapshot", actual.getShardManagerSnapshot());
+        } else {
+            assertEquals("ShardManagerSnapshot", expected.getShardManagerSnapshot().getShardList(),
+                    actual.getShardManagerSnapshot().getShardList());
+        }
+
         assertEquals("ShardSnapshots size", expected.getShardSnapshots().size(), actual.getShardSnapshots().size());
         for (int i = 0; i < expected.getShardSnapshots().size(); i++) {
             assertEquals("ShardSnapshot " + (i + 1) + " name", expected.getShardSnapshots().get(i).getName(),
         assertEquals("ShardSnapshots size", expected.getShardSnapshots().size(), actual.getShardSnapshots().size());
         for (int i = 0; i < expected.getShardSnapshots().size(); i++) {
             assertEquals("ShardSnapshot " + (i + 1) + " name", expected.getShardSnapshots().get(i).getName(),
@@ -121,7 +126,7 @@ public class DatastoreSnapshotRestoreTest {
     }
 
     private static ShardManagerSnapshot newShardManagerSnapshot(String... shards) {
     }
 
     private static ShardManagerSnapshot newShardManagerSnapshot(String... shards) {
-        return ShardManagerSnapshot.forShardList(Arrays.asList(shards));
+        return new ShardManagerSnapshot(Arrays.asList(shards));
     }
 
     private static Snapshot newSnapshot(YangInstanceIdentifier path, NormalizedNode<?, ?> node)
     }
 
     private static Snapshot newSnapshot(YangInstanceIdentifier path, NormalizedNode<?, ?> node)
index 989ed46ca38a34b06f5ce1b5be86ff392a16d7bb..8c8e329e14df9c4e8e27eb9f217260f331cb08b2 100644 (file)
@@ -57,8 +57,9 @@ public class DatastoreSnapshotListTest {
 
         NormalizedNode<?, ?> legacyConfigRoot2 = toRootNode(PeopleModel.BASE_PATH, PeopleModel.emptyContainer());
 
 
         NormalizedNode<?, ?> legacyConfigRoot2 = toRootNode(PeopleModel.BASE_PATH, PeopleModel.emptyContainer());
 
+        ShardManagerSnapshot legacyShardManagerSnapshot = newLegacyShardManagerSnapshot("config-one", "config-two");
         DatastoreSnapshot legacyConfigSnapshot = new DatastoreSnapshot("config",
         DatastoreSnapshot legacyConfigSnapshot = new DatastoreSnapshot("config",
-                SerializationUtils.serialize(newLegacyShardManagerSnapshot("config-one", "config-two")),
+                SerializationUtils.serialize(legacyShardManagerSnapshot),
                 Arrays.asList(newLegacyShardSnapshot("config-one", newLegacySnapshot(legacyConfigRoot1)),
                     newLegacyShardSnapshot("config-two", newLegacySnapshot(legacyConfigRoot2))));
 
                 Arrays.asList(newLegacyShardSnapshot("config-one", newLegacySnapshot(legacyConfigRoot1)),
                     newLegacyShardSnapshot("config-two", newLegacySnapshot(legacyConfigRoot2))));
 
@@ -73,24 +74,29 @@ public class DatastoreSnapshotListTest {
                 SerializationUtils.clone(legacy);
 
         assertEquals("DatastoreSnapshotList size", 2, cloned.size());
                 SerializationUtils.clone(legacy);
 
         assertEquals("DatastoreSnapshotList size", 2, cloned.size());
-        assertDatastoreSnapshotEquals(legacyConfigSnapshot, cloned.get(0), Optional.of(legacyConfigRoot1),
-                Optional.of(legacyConfigRoot2));
-        assertDatastoreSnapshotEquals(legacyOperSnapshot, cloned.get(1), Optional.empty());
+        assertDatastoreSnapshotEquals(legacyConfigSnapshot, cloned.get(0),
+                new org.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot(
+                        legacyShardManagerSnapshot.getShardList()),
+                Optional.of(legacyConfigRoot1), Optional.of(legacyConfigRoot2));
+        assertDatastoreSnapshotEquals(legacyOperSnapshot, cloned.get(1),
+                (org.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot)null,
+                Optional.empty());
     }
 
     }
 
+    @SuppressWarnings("unchecked")
     private void assertDatastoreSnapshotEquals(DatastoreSnapshot legacy,
             org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot actual,
     private void assertDatastoreSnapshotEquals(DatastoreSnapshot legacy,
             org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot actual,
+            org.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot expShardMgrSnapshot,
             Optional<NormalizedNode<?, ?>>... shardRoots) throws IOException {
         assertEquals("Type", legacy.getType(), actual.getType());
 
         if (legacy.getShardManagerSnapshot() == null) {
             assertNull("Expected null ShardManagerSnapshot", actual.getShardManagerSnapshot());
         } else {
             Optional<NormalizedNode<?, ?>>... shardRoots) throws IOException {
         assertEquals("Type", legacy.getType(), actual.getType());
 
         if (legacy.getShardManagerSnapshot() == null) {
             assertNull("Expected null ShardManagerSnapshot", actual.getShardManagerSnapshot());
         } else {
-            ShardManagerSnapshot legacyShardManagerSnapshot =
-                    (ShardManagerSnapshot) SerializationUtils.deserialize(legacy.getShardManagerSnapshot());
-            ShardManagerSnapshot actualShardManagerSnapshot =
-                    (ShardManagerSnapshot) SerializationUtils.deserialize(actual.getShardManagerSnapshot());
-            assertEquals("ShardManagerSnapshot", legacyShardManagerSnapshot.getShardList(),
+            org.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot actualShardManagerSnapshot =
+                (org.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot)
+                    SerializationUtils.deserialize(legacy.getShardManagerSnapshot());
+            assertEquals("ShardManagerSnapshot", expShardMgrSnapshot.getShardList(),
                     actualShardManagerSnapshot.getShardList());
         }
 
                     actualShardManagerSnapshot.getShardList());
         }
 
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/persisted/ShardManagerSnapshotTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/persisted/ShardManagerSnapshotTest.java
new file mode 100644 (file)
index 0000000..7e62963
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017 Brocade Communications 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 static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import org.apache.commons.lang.SerializationUtils;
+import org.junit.Test;
+
+/**
+ * Unit tests for ShardManagerSnapshot.
+ *
+ * @author Thomas Pantelis
+ */
+public class ShardManagerSnapshotTest {
+
+    @Test
+    public void testSerialization() {
+        ShardManagerSnapshot expected = new ShardManagerSnapshot(Arrays.asList("shard1", "shard2"));
+        ShardManagerSnapshot cloned = (ShardManagerSnapshot) SerializationUtils.clone(expected);
+
+        assertEquals("getShardList", expected.getShardList(), cloned.getShardList());
+    }
+}
index 5085cdd305bdb5a5e5636cab31485b9cdd692ca5..76af089b4d29bd4c13c78ff9b9f42a919c7592b6 100644 (file)
@@ -7,7 +7,6 @@
  */
 package org.opendaylight.controller.cluster.datastore.shardmanager;
 
  */
 package org.opendaylight.controller.cluster.datastore.shardmanager;
 
-import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 
 import akka.actor.ActorRef;
 import static org.junit.Assert.assertEquals;
 
 import akka.actor.ActorRef;
@@ -25,6 +24,7 @@ import org.opendaylight.controller.cluster.datastore.AbstractActorTest;
 import org.opendaylight.controller.cluster.datastore.identifiers.ShardIdentifier;
 import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot;
 import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot.ShardSnapshot;
 import org.opendaylight.controller.cluster.datastore.identifiers.ShardIdentifier;
 import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot;
 import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot.ShardSnapshot;
+import org.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot;
 import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
 import org.opendaylight.controller.cluster.raft.client.messages.GetSnapshotReply;
 import org.opendaylight.controller.cluster.raft.persisted.ByteState;
 import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
 import org.opendaylight.controller.cluster.raft.client.messages.GetSnapshotReply;
 import org.opendaylight.controller.cluster.raft.persisted.ByteState;
@@ -44,9 +44,10 @@ public class ShardManagerGetSnapshotReplyActorTest extends AbstractActorTest {
     public void testSuccess() {
         JavaTestKit kit = new JavaTestKit(getSystem());
 
     public void testSuccess() {
         JavaTestKit kit = new JavaTestKit(getSystem());
 
-        byte[] shardManagerSnapshot = new byte[]{0,5,9};
+        List<String> shardList = Arrays.asList("shard1", "shard2", "shard3");
+        ShardManagerSnapshot shardManagerSnapshot = new ShardManagerSnapshot(shardList);
         ActorRef replyActor = getSystem().actorOf(ShardManagerGetSnapshotReplyActor.props(
         ActorRef replyActor = getSystem().actorOf(ShardManagerGetSnapshotReplyActor.props(
-                Arrays.asList("shard1", "shard2", "shard3"), "config", shardManagerSnapshot, kit.getRef(),
+                shardList, "config", shardManagerSnapshot, kit.getRef(),
                 "shard-manager", Duration.create(100, TimeUnit.SECONDS)), "testSuccess");
 
         kit.watch(replyActor);
                 "shard-manager", Duration.create(100, TimeUnit.SECONDS)), "testSuccess");
 
         kit.watch(replyActor);
@@ -71,7 +72,8 @@ public class ShardManagerGetSnapshotReplyActorTest extends AbstractActorTest {
         DatastoreSnapshot datastoreSnapshot = kit.expectMsgClass(DatastoreSnapshot.class);
 
         assertEquals("getType", "config", datastoreSnapshot.getType());
         DatastoreSnapshot datastoreSnapshot = kit.expectMsgClass(DatastoreSnapshot.class);
 
         assertEquals("getType", "config", datastoreSnapshot.getType());
-        assertArrayEquals("getShardManagerSnapshot", shardManagerSnapshot, datastoreSnapshot.getShardManagerSnapshot());
+        assertEquals("getShardManagerSnapshot", shardManagerSnapshot.getShardList(),
+                datastoreSnapshot.getShardManagerSnapshot().getShardList());
         List<ShardSnapshot> shardSnapshots = datastoreSnapshot.getShardSnapshots();
         assertEquals("ShardSnapshot size", 3, shardSnapshots.size());
         assertEquals("ShardSnapshot 1 getName", "shard1", shardSnapshots.get(0).getName());
         List<ShardSnapshot> shardSnapshots = datastoreSnapshot.getShardSnapshots();
         assertEquals("ShardSnapshot size", 3, shardSnapshots.size());
         assertEquals("ShardSnapshot 1 getName", "shard1", shardSnapshots.get(0).getName());
@@ -91,9 +93,8 @@ public class ShardManagerGetSnapshotReplyActorTest extends AbstractActorTest {
     public void testGetSnapshotFailureReply() {
         JavaTestKit kit = new JavaTestKit(getSystem());
 
     public void testGetSnapshotFailureReply() {
         JavaTestKit kit = new JavaTestKit(getSystem());
 
-        byte[] shardManagerSnapshot = new byte[]{0,5,9};
         ActorRef replyActor = getSystem().actorOf(ShardManagerGetSnapshotReplyActor.props(
         ActorRef replyActor = getSystem().actorOf(ShardManagerGetSnapshotReplyActor.props(
-                Arrays.asList("shard1", "shard2"), "config", shardManagerSnapshot, kit.getRef(), "shard-manager",
+                Arrays.asList("shard1", "shard2"), "config", null, kit.getRef(), "shard-manager",
                 Duration.create(100, TimeUnit.SECONDS)), "testGetSnapshotFailureReply");
 
         kit.watch(replyActor);
                 Duration.create(100, TimeUnit.SECONDS)), "testGetSnapshotFailureReply");
 
         kit.watch(replyActor);
@@ -112,9 +113,8 @@ public class ShardManagerGetSnapshotReplyActorTest extends AbstractActorTest {
     public void testGetSnapshotTimeout() {
         JavaTestKit kit = new JavaTestKit(getSystem());
 
     public void testGetSnapshotTimeout() {
         JavaTestKit kit = new JavaTestKit(getSystem());
 
-        byte[] shardManagerSnapshot = new byte[]{0,5,9};
         ActorRef replyActor = getSystem().actorOf(ShardManagerGetSnapshotReplyActor.props(
         ActorRef replyActor = getSystem().actorOf(ShardManagerGetSnapshotReplyActor.props(
-                Arrays.asList("shard1"), "config", shardManagerSnapshot, kit.getRef(), "shard-manager",
+                Arrays.asList("shard1"), "config", null, kit.getRef(), "shard-manager",
                 Duration.create(100, TimeUnit.MILLISECONDS)), "testGetSnapshotTimeout");
 
         kit.watch(replyActor);
                 Duration.create(100, TimeUnit.MILLISECONDS)), "testGetSnapshotTimeout");
 
         kit.watch(replyActor);
index ed7b1eef6a770e1f2553fd60b6c41d239e8bc5cb..ffa264141c412251bdadaf133609f80ea2af7778 100644 (file)
@@ -59,7 +59,6 @@ import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.stream.Collectors;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.stream.Collectors;
-import org.apache.commons.lang3.SerializationUtils;
 import org.junit.Test;
 import org.mockito.Mockito;
 import org.opendaylight.controller.cluster.access.concepts.MemberName;
 import org.junit.Test;
 import org.mockito.Mockito;
 import org.opendaylight.controller.cluster.access.concepts.MemberName;
@@ -97,6 +96,7 @@ import org.opendaylight.controller.cluster.datastore.messages.ShardLeaderStateCh
 import org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext;
 import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot;
 import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot.ShardSnapshot;
 import org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext;
 import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot;
 import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot.ShardSnapshot;
+import org.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot;
 import org.opendaylight.controller.cluster.datastore.utils.ForwardingActor;
 import org.opendaylight.controller.cluster.datastore.utils.MockClusterWrapper;
 import org.opendaylight.controller.cluster.datastore.utils.MockConfiguration;
 import org.opendaylight.controller.cluster.datastore.utils.ForwardingActor;
 import org.opendaylight.controller.cluster.datastore.utils.MockClusterWrapper;
 import org.opendaylight.controller.cluster.datastore.utils.MockConfiguration;
@@ -1372,9 +1372,8 @@ public class ShardManagerTest extends AbstractShardManagerTest {
         assertEquals("Shard names", Sets.newHashSet("shard1", "shard2", "astronauts"), Sets.newHashSet(
                 Lists.transform(datastoreSnapshot.getShardSnapshots(), shardNameTransformer)));
 
         assertEquals("Shard names", Sets.newHashSet("shard1", "shard2", "astronauts"), Sets.newHashSet(
                 Lists.transform(datastoreSnapshot.getShardSnapshots(), shardNameTransformer)));
 
-        byte[] snapshotBytes = datastoreSnapshot.getShardManagerSnapshot();
-        assertNotNull("Expected ShardManagerSnapshot", snapshotBytes);
-        ShardManagerSnapshot snapshot = SerializationUtils.deserialize(snapshotBytes);
+        ShardManagerSnapshot snapshot = datastoreSnapshot.getShardManagerSnapshot();
+        assertNotNull("Expected ShardManagerSnapshot", snapshot);
         assertEquals("Shard names", Sets.newHashSet("shard1", "shard2", "astronauts"),
                 Sets.newHashSet(snapshot.getShardList()));
 
         assertEquals("Shard names", Sets.newHashSet("shard1", "shard2", "astronauts"),
                 Sets.newHashSet(snapshot.getShardList()));
 
@@ -1394,8 +1393,8 @@ public class ShardManagerTest extends AbstractShardManagerTest {
                 .put("astronauts", Collections.<String>emptyList()).build());
 
         ShardManagerSnapshot snapshot = new ShardManagerSnapshot(Arrays.asList("shard1", "shard2", "astronauts"));
                 .put("astronauts", Collections.<String>emptyList()).build());
 
         ShardManagerSnapshot snapshot = new ShardManagerSnapshot(Arrays.asList("shard1", "shard2", "astronauts"));
-        DatastoreSnapshot restoreFromSnapshot = new DatastoreSnapshot(shardMrgIDSuffix,
-                SerializationUtils.serialize(snapshot), Collections.<ShardSnapshot>emptyList());
+        DatastoreSnapshot restoreFromSnapshot = new DatastoreSnapshot(shardMrgIDSuffix, snapshot,
+                Collections.<ShardSnapshot>emptyList());
         TestActorRef<TestShardManager> shardManager = actorFactory.createTestActor(newTestShardMgrBuilder(mockConfig)
                 .restoreFromSnapshot(restoreFromSnapshot).props().withDispatcher(Dispatchers.DefaultDispatcherId()));
 
         TestActorRef<TestShardManager> shardManager = actorFactory.createTestActor(newTestShardMgrBuilder(mockConfig)
                 .restoreFromSnapshot(restoreFromSnapshot).props().withDispatcher(Dispatchers.DefaultDispatcherId()));
 
@@ -1413,11 +1412,9 @@ public class ShardManagerTest extends AbstractShardManagerTest {
 
         assertEquals("getType", shardMrgIDSuffix, datastoreSnapshot.getType());
 
 
         assertEquals("getType", shardMrgIDSuffix, datastoreSnapshot.getType());
 
-        byte[] snapshotBytes = datastoreSnapshot.getShardManagerSnapshot();
-        assertNotNull("Expected ShardManagerSnapshot", snapshotBytes);
-        snapshot = SerializationUtils.deserialize(snapshotBytes);
+        assertNotNull("Expected ShardManagerSnapshot", datastoreSnapshot.getShardManagerSnapshot());
         assertEquals("Shard names", Sets.newHashSet("shard1", "shard2", "astronauts"),
         assertEquals("Shard names", Sets.newHashSet("shard1", "shard2", "astronauts"),
-                Sets.newHashSet(snapshot.getShardList()));
+                Sets.newHashSet(datastoreSnapshot.getShardManagerSnapshot().getShardList()));
 
         LOG.info("testRestoreFromSnapshot ending");
     }
 
         LOG.info("testRestoreFromSnapshot ending");
     }