From 95c296a7c1e8e186a88a0a0dc82e080b2185db33 Mon Sep 17 00:00:00 2001 From: Tom Pantelis Date: Wed, 25 Jan 2017 08:04:57 -0500 Subject: [PATCH] Bug 7521: Convert byte[] to ShardManagerSnapshot in DatastoreSnapshot 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 --- .../datastore/ShardManagerSnapshot.java | 2 +- .../messages/DatastoreSnapshotList.java | 19 +++- .../persisted/DatastoreSnapshot.java | 15 +--- .../persisted/ShardManagerSnapshot.java | 87 +++++++++++++++++++ .../datastore/shardmanager/ShardManager.java | 23 ++--- .../ShardManagerGetSnapshotReplyActor.java | 11 +-- .../shardmanager/ShardManagerSnapshot.java | 10 ++- .../DatastoreSnapshotRestoreTest.java | 17 ++-- .../messages/DatastoreSnapshotListTest.java | 24 +++-- .../persisted/ShardManagerSnapshotTest.java | 30 +++++++ ...ShardManagerGetSnapshotReplyActorTest.java | 16 ++-- .../shardmanager/ShardManagerTest.java | 17 ++-- 12 files changed, 198 insertions(+), 73 deletions(-) create mode 100644 opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/ShardManagerSnapshot.java create mode 100644 opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/persisted/ShardManagerSnapshotTest.java diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ShardManagerSnapshot.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ShardManagerSnapshot.java index eb8c139903..994f0761b0 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ShardManagerSnapshot.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ShardManagerSnapshot.java @@ -40,6 +40,6 @@ public class ShardManagerSnapshot implements Serializable { } 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); } } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/DatastoreSnapshotList.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/DatastoreSnapshotList.java index 8400e0c3e2..42f3129728 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/DatastoreSnapshotList.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/messages/DatastoreSnapshotList.java @@ -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 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; @@ -38,25 +39,37 @@ public class DatastoreSnapshotList extends ArrayList { 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); } + 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 fromLegacy(List from) throws IOException, ClassNotFoundException { List 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; } - 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(); diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/DatastoreSnapshot.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/DatastoreSnapshot.java index 9eb8a066d5..fec44082ec 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/DatastoreSnapshot.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/DatastoreSnapshot.java @@ -9,7 +9,6 @@ package org.opendaylight.controller.cluster.datastore.persisted; 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; @@ -59,7 +58,7 @@ public class DatastoreSnapshot implements Serializable { @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 shardSnapshots = new ArrayList<>(size); @@ -76,13 +75,10 @@ public class DatastoreSnapshot implements Serializable { } private final String type; - private final byte[] shardManagerSnapshot; + private final ShardManagerSnapshot shardManagerSnapshot; private final List 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 shardSnapshots) { this.type = Preconditions.checkNotNull(type); this.shardManagerSnapshot = shardManagerSnapshot; @@ -94,11 +90,8 @@ public class DatastoreSnapshot implements Serializable { 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 - public byte[] getShardManagerSnapshot() { + public ShardManagerSnapshot getShardManagerSnapshot() { 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 index 0000000000..6bb6ea8b30 --- /dev/null +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/ShardManagerSnapshot.java @@ -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 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 shardList; + + public ShardManagerSnapshot(@Nonnull final List shardList) { + this.shardList = ImmutableList.copyOf(shardList); + } + + public List getShardList() { + return this.shardList; + } + + @SuppressWarnings("static-method") + private Object writeReplace() { + return new Proxy(this); + } + + @Override + public String toString() { + return "ShardManagerSnapshot [ShardList = " + shardList + " ]"; + } +} diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManager.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManager.java index 736742cb1c..b2c9d30184 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManager.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManager.java @@ -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 java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.ObjectInputStream; 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 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; @@ -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.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; @@ -412,13 +409,8 @@ class ShardManager extends AbstractUntypedPersistentActorWithMetering { return; } - byte[] shardManagerSnapshot = null; - if (currentSnapshot != null) { - shardManagerSnapshot = SerializationUtils.serialize(currentSnapshot); - } - 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()) { @@ -724,16 +716,11 @@ class ShardManager extends AbstractUntypedPersistentActorWithMetering { 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(); diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManagerGetSnapshotReplyActor.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManagerGetSnapshotReplyActor.java index d64b1086dd..c474cf89fc 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManagerGetSnapshotReplyActor.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManagerGetSnapshotReplyActor.java @@ -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.persisted.ShardManagerSnapshot; 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 shardNames, String datastoreType, byte[] shardManagerSnapshot, - ActorRef replyToActor, String id, Duration receiveTimeout) { + public static Props props(Collection shardNames, String datastoreType, + ShardManagerSnapshot shardManagerSnapshot, ActorRef replyToActor, String id, Duration 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 shardNames; final String datastoreType; - final byte[] shardManagerSnapshot; + final ShardManagerSnapshot shardManagerSnapshot; final ActorRef replyToActor; final String id; final Duration receiveTimeout; - Params(Collection shardNames, String datastoreType, byte[] shardManagerSnapshot, ActorRef replyToActor, - String id, Duration receiveTimeout) { + Params(Collection shardNames, String datastoreType, ShardManagerSnapshot shardManagerSnapshot, + ActorRef replyToActor, String id, Duration receiveTimeout) { this.shardNames = shardNames; this.datastoreType = datastoreType; this.shardManagerSnapshot = shardManagerSnapshot; diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManagerSnapshot.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManagerSnapshot.java index d784996bac..46fccc745d 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManagerSnapshot.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManagerSnapshot.java @@ -15,13 +15,15 @@ import javax.annotation.Nonnull; /** * 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 shardList; - ShardManagerSnapshot(final @Nonnull List shardList) { + ShardManagerSnapshot(@Nonnull final List shardList) { this.shardList = ImmutableList.copyOf(shardList); } @@ -40,6 +42,10 @@ public final class ShardManagerSnapshot implements Serializable { 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 + " ]"; diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DatastoreSnapshotRestoreTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DatastoreSnapshotRestoreTest.java index bbbd95fd08..67af9bb348 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DatastoreSnapshotRestoreTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DatastoreSnapshotRestoreTest.java @@ -18,15 +18,14 @@ import java.io.FileOutputStream; 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.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot; 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; @@ -62,7 +61,7 @@ public class DatastoreSnapshotRestoreTest { 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", @@ -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()); - 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(), @@ -121,7 +126,7 @@ public class DatastoreSnapshotRestoreTest { } 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) diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/messages/DatastoreSnapshotListTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/messages/DatastoreSnapshotListTest.java index 989ed46ca3..8c8e329e14 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/messages/DatastoreSnapshotListTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/messages/DatastoreSnapshotListTest.java @@ -57,8 +57,9 @@ public class DatastoreSnapshotListTest { NormalizedNode legacyConfigRoot2 = toRootNode(PeopleModel.BASE_PATH, PeopleModel.emptyContainer()); + ShardManagerSnapshot legacyShardManagerSnapshot = newLegacyShardManagerSnapshot("config-one", "config-two"); 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)))); @@ -73,24 +74,29 @@ public class DatastoreSnapshotListTest { 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, + org.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot expShardMgrSnapshot, Optional>... 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()); } 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 index 0000000000..7e62963b64 --- /dev/null +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/persisted/ShardManagerSnapshotTest.java @@ -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()); + } +} diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManagerGetSnapshotReplyActorTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManagerGetSnapshotReplyActorTest.java index 5085cdd305..76af089b4d 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManagerGetSnapshotReplyActorTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManagerGetSnapshotReplyActorTest.java @@ -7,7 +7,6 @@ */ package org.opendaylight.controller.cluster.datastore.shardmanager; -import static org.junit.Assert.assertArrayEquals; 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.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; @@ -44,9 +44,10 @@ public class ShardManagerGetSnapshotReplyActorTest extends AbstractActorTest { public void testSuccess() { JavaTestKit kit = new JavaTestKit(getSystem()); - byte[] shardManagerSnapshot = new byte[]{0,5,9}; + List shardList = Arrays.asList("shard1", "shard2", "shard3"); + ShardManagerSnapshot shardManagerSnapshot = new ShardManagerSnapshot(shardList); 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); @@ -71,7 +72,8 @@ public class ShardManagerGetSnapshotReplyActorTest extends AbstractActorTest { DatastoreSnapshot datastoreSnapshot = kit.expectMsgClass(DatastoreSnapshot.class); assertEquals("getType", "config", datastoreSnapshot.getType()); - assertArrayEquals("getShardManagerSnapshot", shardManagerSnapshot, datastoreSnapshot.getShardManagerSnapshot()); + assertEquals("getShardManagerSnapshot", shardManagerSnapshot.getShardList(), + datastoreSnapshot.getShardManagerSnapshot().getShardList()); List 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()); - byte[] shardManagerSnapshot = new byte[]{0,5,9}; 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); @@ -112,9 +113,8 @@ public class ShardManagerGetSnapshotReplyActorTest extends AbstractActorTest { public void testGetSnapshotTimeout() { JavaTestKit kit = new JavaTestKit(getSystem()); - byte[] shardManagerSnapshot = new byte[]{0,5,9}; 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); diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManagerTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManagerTest.java index ed7b1eef6a..ffa264141c 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManagerTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/shardmanager/ShardManagerTest.java @@ -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 org.apache.commons.lang3.SerializationUtils; 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.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; @@ -1372,9 +1372,8 @@ public class ShardManagerTest extends AbstractShardManagerTest { 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())); @@ -1394,8 +1393,8 @@ public class ShardManagerTest extends AbstractShardManagerTest { .put("astronauts", Collections.emptyList()).build()); ShardManagerSnapshot snapshot = new ShardManagerSnapshot(Arrays.asList("shard1", "shard2", "astronauts")); - DatastoreSnapshot restoreFromSnapshot = new DatastoreSnapshot(shardMrgIDSuffix, - SerializationUtils.serialize(snapshot), Collections.emptyList()); + DatastoreSnapshot restoreFromSnapshot = new DatastoreSnapshot(shardMrgIDSuffix, snapshot, + Collections.emptyList()); TestActorRef 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()); - 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"), - Sets.newHashSet(snapshot.getShardList())); + Sets.newHashSet(datastoreSnapshot.getShardManagerSnapshot().getShardList())); LOG.info("testRestoreFromSnapshot ending"); } -- 2.36.6