Change ReplicatedLogImplEntry to Externalizable proxy pattern 03/48803/2
authorTom Pantelis <tpanteli@brocade.com>
Tue, 29 Nov 2016 16:34:50 +0000 (11:34 -0500)
committerTom Pantelis <tpanteli@brocade.com>
Thu, 1 Dec 2016 13:06:34 +0000 (13:06 +0000)
The Externalizable proxy pattern decreases serialized sized as
it avoids serializing the full class info. We need to keep
ReplicatedLogImplEntry for persistence backwards compatibility.
A new SimpleReplicatedLogEntry class was added to implement the
Externalizable proxy pattern. ReplicatedLogImplEntry "readResolves"
to SimpleReplicatedLogEntry. Also, SimpleReplicatedLogEntry
implements MigratedSerializable to cause a snapshot on upgrade
enabling us to remove ReplicatedLogImplEntry in the next release.

Change-Id: Iaf5c8f6b271c3ead43a80ac905412b4cb5a9efa2
Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
17 files changed:
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActor.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ReplicatedLogImplEntry.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/AppendEntries.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/persisted/SimpleReplicatedLogEntry.java [new file with mode: 0644]
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/MigratedMessagesTest.java
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/MockRaftActorContext.java
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/NonVotingFollowerIntegrationTest.java
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/RaftActorServerConfigurationSupportTest.java
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/RaftActorTest.java
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/ReplicatedLogImplEntryTest.java
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/ReplicationAndSnapshotsIntegrationTest.java
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/ReplicationAndSnapshotsWithLaggingFollowerIntegrationTest.java
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/SnapshotTest.java
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/LeaderTest.java
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/messages/AppendEntriesTest.java
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/persisted/SimpleReplicatedLogEntryTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTest.java

index 4655150..8ed92d4 100644 (file)
@@ -51,6 +51,7 @@ import org.opendaylight.controller.cluster.raft.client.messages.OnDemandRaftStat
 import org.opendaylight.controller.cluster.raft.client.messages.Shutdown;
 import org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries;
 import org.opendaylight.controller.cluster.raft.persisted.NoopPayload;
+import org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry;
 import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
 import org.opendaylight.yangtools.concepts.Identifier;
 import org.opendaylight.yangtools.concepts.Immutable;
@@ -518,7 +519,7 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor {
      */
     protected final void persistData(final ActorRef clientActor, final Identifier identifier, final Payload data) {
 
-        ReplicatedLogEntry replicatedLogEntry = new ReplicatedLogImplEntry(
+        ReplicatedLogEntry replicatedLogEntry = new SimpleReplicatedLogEntry(
             context.getReplicatedLog().lastIndex() + 1,
             context.getTermInformation().getCurrentTerm(), data);
         replicatedLogEntry.setPersistencePending(true);
index 8019359..c8ee634 100644 (file)
@@ -14,7 +14,10 @@ import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payloa
 
 /**
  * A {@link ReplicatedLogEntry} implementation.
+ *
+ * @deprecated Use {@link org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry} instead.
  */
+@Deprecated
 public class ReplicatedLogImplEntry implements ReplicatedLogEntry, Serializable {
     private static final long serialVersionUID = -9085798014576489130L;
 
@@ -56,6 +59,11 @@ public class ReplicatedLogImplEntry implements ReplicatedLogEntry, Serializable
         return getData().size();
     }
 
+    private Object readResolve() {
+        return org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry.createMigrated(
+                index, term, payload);
+    }
+
     @Override
     public boolean isPersistencePending() {
         return persistencePending;
index 7ebc857..0177946 100644 (file)
@@ -15,7 +15,7 @@ import java.io.ObjectOutput;
 import java.util.ArrayList;
 import java.util.List;
 import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
-import org.opendaylight.controller.cluster.raft.ReplicatedLogImplEntry;
+import org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry;
 import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
 
 /**
@@ -145,7 +145,7 @@ public class AppendEntries extends AbstractRaftRPC {
             int size = in.readInt();
             List<ReplicatedLogEntry> entries = new ArrayList<>(size);
             for (int i = 0; i < size; i++) {
-                entries.add(new ReplicatedLogImplEntry(in.readLong(), in.readLong(), (Payload) in.readObject()));
+                entries.add(new SimpleReplicatedLogEntry(in.readLong(), in.readLong(), (Payload) in.readObject()));
             }
 
             appendEntries = new AppendEntries(term, leaderId, prevLogIndex, prevLogTerm, entries, leaderCommit,
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/persisted/SimpleReplicatedLogEntry.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/persisted/SimpleReplicatedLogEntry.java
new file mode 100644 (file)
index 0000000..3dc5a28
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2014 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.raft.persisted;
+
+import com.google.common.base.Preconditions;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
+import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
+
+/**
+ * A {@link ReplicatedLogEntry} implementation.
+ *
+ * @author Thomas Pantelis
+ */
+public class SimpleReplicatedLogEntry implements ReplicatedLogEntry, MigratedSerializable {
+    private static final class Proxy implements Externalizable {
+        private static final long serialVersionUID = 1L;
+
+        private ReplicatedLogEntry replicatedLogEntry;
+
+        // 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 ReplicatedLogEntry replicatedLogEntry) {
+            this.replicatedLogEntry = replicatedLogEntry;
+        }
+
+        @Override
+        public void writeExternal(final ObjectOutput out) throws IOException {
+            out.writeLong(replicatedLogEntry.getIndex());
+            out.writeLong(replicatedLogEntry.getTerm());
+            out.writeObject(replicatedLogEntry.getData());
+        }
+
+        @Override
+        public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
+            replicatedLogEntry = new SimpleReplicatedLogEntry(in.readLong(), in.readLong(), (Payload) in.readObject());
+        }
+
+        private Object readResolve() {
+            return replicatedLogEntry;
+        }
+    }
+
+    private static final long serialVersionUID = 1L;
+
+    private final long index;
+    private final long term;
+    private final Payload payload;
+    private boolean persistencePending;
+    private final boolean migrated;
+
+    private SimpleReplicatedLogEntry(long index, long term, Payload payload, boolean migrated) {
+        this.index = index;
+        this.term = term;
+        this.payload = Preconditions.checkNotNull(payload);
+        this.migrated = migrated;
+    }
+
+    /**
+     * Constructs an instance.
+     *
+     * @param index the index
+     * @param term the term
+     * @param payload the payload
+     */
+    public SimpleReplicatedLogEntry(final long index, final long term, final Payload payload) {
+        this(index, term, payload, false);
+    }
+
+    @Deprecated
+    public static ReplicatedLogEntry createMigrated(final long index, final long term, final Payload payload) {
+        return new SimpleReplicatedLogEntry(index, term, payload, true);
+    }
+
+    @Override
+    public Payload getData() {
+        return payload;
+    }
+
+    @Override
+    public long getTerm() {
+        return term;
+    }
+
+    @Override
+    public long getIndex() {
+        return index;
+    }
+
+    @Override
+    public int size() {
+        return getData().size();
+    }
+
+    @Override
+    public boolean isPersistencePending() {
+        return persistencePending;
+    }
+
+    @Override
+    public void setPersistencePending(boolean pending) {
+        persistencePending = pending;
+    }
+
+    @Override
+    public boolean isMigrated() {
+        return migrated;
+    }
+
+    @Override
+    public Object writeReplace() {
+        return new Proxy(this);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + payload.hashCode();
+        result = prime * result + (int) (index ^ index >>> 32);
+        result = prime * result + (int) (term ^ term >>> 32);
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+
+        SimpleReplicatedLogEntry other = (SimpleReplicatedLogEntry) obj;
+        return index == other.index && term == other.term && payload.equals(other.payload);
+    }
+
+    @Override
+    public String toString() {
+        return "SimpleReplicatedLogEntry [index=" + index + ", term=" + term + ", payload=" + payload + "]";
+    }
+}
index 08967d2..9ce8909 100644 (file)
@@ -14,6 +14,7 @@ import akka.dispatch.Dispatchers;
 import akka.testkit.JavaTestKit;
 import akka.testkit.TestActorRef;
 import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.util.concurrent.Uninterruptibles;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -24,8 +25,10 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshotReply;
+import org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries;
 import org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload;
 import org.opendaylight.controller.cluster.raft.persisted.ServerInfo;
+import org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry;
 import org.opendaylight.controller.cluster.raft.persisted.UpdateElectionTerm;
 import org.opendaylight.controller.cluster.raft.policy.DisableElectionsRaftPolicy;
 import org.opendaylight.controller.cluster.raft.utils.InMemoryJournal;
@@ -131,7 +134,7 @@ public class MigratedMessagesTest extends AbstractActorTest {
         String persistenceId = factory.generateActorId("test-actor-");
 
         InMemoryJournal.addEntry(persistenceId, 1, new UpdateElectionTerm(1, persistenceId));
-        InMemoryJournal.addEntry(persistenceId, 2, new ReplicatedLogImplEntry(0, 1,
+        InMemoryJournal.addEntry(persistenceId, 2, new SimpleReplicatedLogEntry(0, 1,
                 new MockRaftActorContext.MockPayload("A")));
         InMemoryJournal.addEntry(persistenceId, 3,
                 new org.opendaylight.controller.cluster.raft.base.messages.ApplyJournalEntries(0));
@@ -149,7 +152,13 @@ public class MigratedMessagesTest extends AbstractActorTest {
 
     @Test
     public void testNoSnapshotAfterStartupWithNoMigratedMessages() {
+        TEST_LOG.info("testNoSnapshotAfterStartupWithNoMigratedMessages starting");
         String id = factory.generateActorId("test-actor-");
+
+        InMemoryJournal.addEntry(id, 1, new UpdateElectionTerm(1, id));
+        InMemoryJournal.addEntry(id, 2, new SimpleReplicatedLogEntry(0, 1, new MockRaftActorContext.MockPayload("A")));
+        InMemoryJournal.addEntry(id, 3, new ApplyJournalEntries(0));
+
         DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
         config.setCustomRaftPolicyImplementationClass(DisableElectionsRaftPolicy.class.getName());
 
@@ -175,6 +184,29 @@ public class MigratedMessagesTest extends AbstractActorTest {
 
         List<Snapshot> snapshots = InMemorySnapshotStore.getSnapshots(id, Snapshot.class);
         assertEquals("Snapshots", 0, snapshots.size());
+
+        TEST_LOG.info("testNoSnapshotAfterStartupWithNoMigratedMessages ending");
+    }
+
+    @Test
+    public void testSnapshotAfterStartupWithMigratedReplicatedLogEntry() {
+        TEST_LOG.info("testSnapshotAfterStartupWithMigratedReplicatedLogEntry starting");
+
+        String persistenceId = factory.generateActorId("test-actor-");
+
+        InMemoryJournal.addEntry(persistenceId, 1, new UpdateElectionTerm(1, persistenceId));
+        MockRaftActorContext.MockPayload expPayload = new MockRaftActorContext.MockPayload("A");
+        InMemoryJournal.addEntry(persistenceId, 2, new org.opendaylight.controller.cluster.raft.ReplicatedLogImplEntry(
+                0, 1, expPayload));
+
+        doTestSnapshotAfterStartupWithMigratedMessage(persistenceId, true, snapshot -> {
+            assertEquals("Unapplied entries size", 1, snapshot.getUnAppliedEntries().size());
+            assertEquals("Unapplied entry term", 1, snapshot.getUnAppliedEntries().get(0).getTerm());
+            assertEquals("Unapplied entry index", 0, snapshot.getUnAppliedEntries().get(0).getIndex());
+            assertEquals("Unapplied entry data", expPayload, snapshot.getUnAppliedEntries().get(0).getData());
+        });
+
+        TEST_LOG.info("testSnapshotAfterStartupWithMigratedReplicatedLogEntry ending");
     }
 
     private TestActorRef<MockRaftActor> doTestSnapshotAfterStartupWithMigratedServerConfigPayload(boolean persistent) {
@@ -191,7 +223,7 @@ public class MigratedMessagesTest extends AbstractActorTest {
                 new ServerInfo(persistenceId, true), new ServerInfo("downNode", true)));
 
         InMemoryJournal.addEntry(persistenceId, 1, new UpdateElectionTerm(1, persistenceId));
-        InMemoryJournal.addEntry(persistenceId, 3, new ReplicatedLogImplEntry(0, 1, persistedServerConfig));
+        InMemoryJournal.addEntry(persistenceId, 3, new SimpleReplicatedLogEntry(0, 1, persistedServerConfig));
 
         TestActorRef<MockRaftActor> actor = doTestSnapshotAfterStartupWithMigratedMessage(persistenceId,
             persistent, snapshot -> {
@@ -224,7 +256,8 @@ public class MigratedMessagesTest extends AbstractActorTest {
         };
 
         TestActorRef<MockRaftActor> raftActorRef = factory.createTestActor(MockRaftActor.builder().id(id)
-                .config(config).snapshotCohort(snapshotCohort).persistent(Optional.of(persistent)).props()
+                .config(config).snapshotCohort(snapshotCohort).persistent(Optional.of(persistent))
+                .peerAddresses(ImmutableMap.of("peer", "")).props()
                     .withDispatcher(Dispatchers.DefaultDispatcherId()), id);
         MockRaftActor mockRaftActor = raftActorRef.underlyingActor();
 
index d3af205..0bb2e8a 100644 (file)
@@ -19,6 +19,7 @@ import java.util.HashMap;
 import java.util.Map;
 import org.opendaylight.controller.cluster.NonPersistentDataProvider;
 import org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior;
+import org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry;
 import org.opendaylight.controller.cluster.raft.policy.RaftPolicy;
 import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
 import org.slf4j.Logger;
@@ -224,7 +225,7 @@ public class MockRaftActorContext extends RaftActorContextImpl {
     }
 
     // TODO - this class can be removed and use ReplicatedLogImplEntry directly.
-    public static class MockReplicatedLogEntry extends ReplicatedLogImplEntry {
+    public static class MockReplicatedLogEntry extends SimpleReplicatedLogEntry {
         private static final long serialVersionUID = 1L;
 
         public MockReplicatedLogEntry(long term, long index, Payload data) {
@@ -237,14 +238,14 @@ public class MockRaftActorContext extends RaftActorContextImpl {
 
         public  MockReplicatedLogBuilder createEntries(int start, int end, int term) {
             for (int i = start; i < end; i++) {
-                this.mockLog.append(new ReplicatedLogImplEntry(i, term,
+                this.mockLog.append(new SimpleReplicatedLogEntry(i, term,
                         new MockRaftActorContext.MockPayload(Integer.toString(i))));
             }
             return this;
         }
 
         public  MockReplicatedLogBuilder addEntry(int index, int term, MockPayload payload) {
-            this.mockLog.append(new ReplicatedLogImplEntry(index, term, payload));
+            this.mockLog.append(new SimpleReplicatedLogEntry(index, term, payload));
             return this;
         }
 
index 7db9d4c..575c4fb 100644 (file)
@@ -25,6 +25,7 @@ import org.opendaylight.controller.cluster.raft.base.messages.SnapshotComplete;
 import org.opendaylight.controller.cluster.raft.messages.AppendEntries;
 import org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload;
 import org.opendaylight.controller.cluster.raft.persisted.ServerInfo;
+import org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry;
 import org.opendaylight.controller.cluster.raft.persisted.UpdateElectionTerm;
 import org.opendaylight.controller.cluster.raft.policy.DisableElectionsRaftPolicy;
 import org.opendaylight.controller.cluster.raft.utils.InMemoryJournal;
@@ -294,7 +295,7 @@ public class NonVotingFollowerIntegrationTest extends AbstractRaftActorIntegrati
         ServerConfigurationPayload persistedServerConfig = new ServerConfigurationPayload(Arrays.asList(
                 new ServerInfo(leaderId, true), new ServerInfo(follower1Id, false),
                 new ServerInfo(follower2Id, true), new ServerInfo("downPeer", false)));
-        ReplicatedLogImplEntry persistedServerConfigEntry = new ReplicatedLogImplEntry(0, currentTerm,
+        SimpleReplicatedLogEntry persistedServerConfigEntry = new SimpleReplicatedLogEntry(0, currentTerm,
                 persistedServerConfig);
 
         InMemoryJournal.clear();
@@ -402,7 +403,7 @@ public class NonVotingFollowerIntegrationTest extends AbstractRaftActorIntegrati
 
         ServerConfigurationPayload persistedServerConfig = new ServerConfigurationPayload(Arrays.asList(
                 new ServerInfo(leaderId, true), new ServerInfo(follower1Id, false)));
-        ReplicatedLogImplEntry persistedServerConfigEntry = new ReplicatedLogImplEntry(0, persistedTerm,
+        SimpleReplicatedLogEntry persistedServerConfigEntry = new SimpleReplicatedLogEntry(0, persistedTerm,
                 persistedServerConfig);
 
         InMemoryJournal.addEntry(leaderId, 1, new UpdateElectionTerm(persistedTerm, leaderId));
index 9c7322d..43ad1c1 100644 (file)
@@ -60,6 +60,7 @@ import org.opendaylight.controller.cluster.raft.messages.UnInitializedFollowerSn
 import org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries;
 import org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload;
 import org.opendaylight.controller.cluster.raft.persisted.ServerInfo;
+import org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry;
 import org.opendaylight.controller.cluster.raft.persisted.UpdateElectionTerm;
 import org.opendaylight.controller.cluster.raft.policy.DisableElectionsRaftPolicy;
 import org.opendaylight.controller.cluster.raft.utils.ForwardMessageToBehaviorActor;
@@ -212,12 +213,12 @@ public class RaftActorServerConfigurationSupportTest extends AbstractActorTest {
         assertEquals("New follower last applied index", 3, newFollowerActorContext.getLastApplied());
 
         assertEquals("Leader persisted ReplicatedLogImplEntry entries", 0,
-                InMemoryJournal.get(LEADER_ID, ReplicatedLogImplEntry.class).size());
+                InMemoryJournal.get(LEADER_ID, SimpleReplicatedLogEntry.class).size());
         assertEquals("Leader persisted ServerConfigurationPayload entries", 1,
                 InMemoryJournal.get(LEADER_ID, ServerConfigurationPayload.class).size());
 
         assertEquals("New follower persisted ReplicatedLogImplEntry entries", 0,
-                InMemoryJournal.get(NEW_SERVER_ID, ReplicatedLogImplEntry.class).size());
+                InMemoryJournal.get(NEW_SERVER_ID, SimpleReplicatedLogEntry.class).size());
         assertEquals("New follower persisted ServerConfigurationPayload entries", 1,
                 InMemoryJournal.get(NEW_SERVER_ID, ServerConfigurationPayload.class).size());
 
@@ -1131,7 +1132,7 @@ public class RaftActorServerConfigurationSupportTest extends AbstractActorTest {
         ServerConfigurationPayload persistedServerConfig = new ServerConfigurationPayload(Arrays.asList(
                 new ServerInfo(node1ID, false), new ServerInfo(node2ID, false),
                 new ServerInfo("downNode1", true), new ServerInfo("downNode2", true)));
-        ReplicatedLogImplEntry persistedServerConfigEntry = new ReplicatedLogImplEntry(0, 1, persistedServerConfig);
+        SimpleReplicatedLogEntry persistedServerConfigEntry = new SimpleReplicatedLogEntry(0, 1, persistedServerConfig);
 
         InMemoryJournal.addEntry(node1ID, 1, new UpdateElectionTerm(1, "downNode1"));
         InMemoryJournal.addEntry(node1ID, 2, persistedServerConfigEntry);
@@ -1239,7 +1240,7 @@ public class RaftActorServerConfigurationSupportTest extends AbstractActorTest {
 
         ServerConfigurationPayload persistedServerConfig = new ServerConfigurationPayload(Arrays.asList(
                 new ServerInfo(node1ID, false), new ServerInfo(node2ID, true)));
-        ReplicatedLogImplEntry persistedServerConfigEntry = new ReplicatedLogImplEntry(0, 1, persistedServerConfig);
+        SimpleReplicatedLogEntry persistedServerConfigEntry = new SimpleReplicatedLogEntry(0, 1, persistedServerConfig);
 
         InMemoryJournal.addEntry(node1ID, 1, new UpdateElectionTerm(1, "node1"));
         InMemoryJournal.addEntry(node1ID, 2, persistedServerConfigEntry);
@@ -1307,13 +1308,13 @@ public class RaftActorServerConfigurationSupportTest extends AbstractActorTest {
 
         ServerConfigurationPayload persistedServerConfig = new ServerConfigurationPayload(Arrays.asList(
                 new ServerInfo(node1ID, false), new ServerInfo(node2ID, false)));
-        ReplicatedLogImplEntry persistedServerConfigEntry = new ReplicatedLogImplEntry(0, 1, persistedServerConfig);
+        SimpleReplicatedLogEntry persistedServerConfigEntry = new SimpleReplicatedLogEntry(0, 1, persistedServerConfig);
 
         InMemoryJournal.addEntry(node1ID, 1, new UpdateElectionTerm(1, "node1"));
         InMemoryJournal.addEntry(node1ID, 2, persistedServerConfigEntry);
         InMemoryJournal.addEntry(node2ID, 1, new UpdateElectionTerm(1, "node1"));
         InMemoryJournal.addEntry(node2ID, 2, persistedServerConfigEntry);
-        InMemoryJournal.addEntry(node2ID, 3, new ReplicatedLogImplEntry(1, 1,
+        InMemoryJournal.addEntry(node2ID, 3, new SimpleReplicatedLogEntry(1, 1,
                 new MockRaftActorContext.MockPayload("2")));
         InMemoryJournal.addEntry(node2ID, 4, new ApplyJournalEntries(1));
 
@@ -1375,7 +1376,7 @@ public class RaftActorServerConfigurationSupportTest extends AbstractActorTest {
 
         ServerConfigurationPayload persistedServerConfig = new ServerConfigurationPayload(Arrays.asList(
                 new ServerInfo(node1ID, false), new ServerInfo(node2ID, true)));
-        ReplicatedLogImplEntry persistedServerConfigEntry = new ReplicatedLogImplEntry(0, 1, persistedServerConfig);
+        SimpleReplicatedLogEntry persistedServerConfigEntry = new SimpleReplicatedLogEntry(0, 1, persistedServerConfig);
 
         InMemoryJournal.addEntry(node1ID, 1, new UpdateElectionTerm(1, "node1"));
         InMemoryJournal.addEntry(node1ID, 2, persistedServerConfigEntry);
index da0493f..d57c354 100644 (file)
@@ -82,6 +82,7 @@ import org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries;
 import org.opendaylight.controller.cluster.raft.persisted.DeleteEntries;
 import org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload;
 import org.opendaylight.controller.cluster.raft.persisted.ServerInfo;
+import org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry;
 import org.opendaylight.controller.cluster.raft.persisted.UpdateElectionTerm;
 import org.opendaylight.controller.cluster.raft.policy.DisableElectionsRaftPolicy;
 import org.opendaylight.controller.cluster.raft.utils.InMemoryJournal;
@@ -637,7 +638,7 @@ public class RaftActorTest extends AbstractActorTest {
 
         // add another non-replicated entry
         leaderActor.getReplicatedLog().append(
-                new ReplicatedLogImplEntry(8, 1, new MockRaftActorContext.MockPayload("foo-8")));
+                new SimpleReplicatedLogEntry(8, 1, new MockRaftActorContext.MockPayload("foo-8")));
 
         //fake snapshot on index 7, since lastApplied = 7 , we would keep the last applied
         leaderActor.onReceiveCommand(new AppendEntriesReply(follower1Id, 1, true, 7, 1, (short)0));
@@ -1116,8 +1117,7 @@ public class RaftActorTest extends AbstractActorTest {
         config.setCustomRaftPolicyImplementationClass(DisableElectionsRaftPolicy.class.getName());
 
         List<ReplicatedLogEntry> snapshotUnappliedEntries = new ArrayList<>();
-        snapshotUnappliedEntries.add(new MockRaftActorContext.MockReplicatedLogEntry(1, 4,
-                new MockRaftActorContext.MockPayload("E")));
+        snapshotUnappliedEntries.add(new SimpleReplicatedLogEntry(4, 1, new MockRaftActorContext.MockPayload("E")));
 
         int snapshotLastApplied = 3;
         int snapshotLastIndex = 4;
index acf3bee..085861f 100644 (file)
@@ -14,12 +14,14 @@ import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import org.junit.Assert;
 import org.junit.Test;
+import org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry;
 
 /**
  * Unit tests for ReplicatedLogImplEntry.
  *
  * @author Thomas Pantelis
  */
+@Deprecated
 public class ReplicatedLogImplEntryTest {
 
     @Test
@@ -31,7 +33,7 @@ public class ReplicatedLogImplEntryTest {
         try (FileInputStream fis = new FileInputStream("src/test/resources/helium-serialized-ReplicatedLogImplEntry")) {
             ObjectInputStream ois = new ObjectInputStream(fis);
 
-            ReplicatedLogImplEntry entry = (ReplicatedLogImplEntry) ois.readObject();
+            SimpleReplicatedLogEntry entry = (SimpleReplicatedLogEntry) ois.readObject();
             ois.close();
 
             Assert.assertEquals("getIndex", expIndex, entry.getIndex());
index 386108f..0254c6d 100644 (file)
@@ -19,6 +19,7 @@ import org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshotRep
 import org.opendaylight.controller.cluster.raft.messages.AppendEntries;
 import org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply;
 import org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries;
+import org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry;
 import org.opendaylight.controller.cluster.raft.persisted.UpdateElectionTerm;
 import org.opendaylight.controller.cluster.raft.utils.InMemoryJournal;
 import org.opendaylight.controller.cluster.raft.utils.InMemorySnapshotStore;
@@ -31,7 +32,7 @@ import org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor;
  */
 public class ReplicationAndSnapshotsIntegrationTest extends AbstractRaftActorIntegrationTest {
 
-    private List<ReplicatedLogImplEntry> origLeaderJournal;
+    private List<SimpleReplicatedLogEntry> origLeaderJournal;
 
     private MockPayload recoveredPayload0;
     private MockPayload recoveredPayload1;
@@ -51,14 +52,14 @@ public class ReplicationAndSnapshotsIntegrationTest extends AbstractRaftActorInt
         long seqId = 1;
         InMemoryJournal.addEntry(leaderId, seqId++, new UpdateElectionTerm(initialTerm, leaderId));
         recoveredPayload0 = new MockPayload("zero");
-        InMemoryJournal.addEntry(leaderId, seqId++, new ReplicatedLogImplEntry(0, initialTerm, recoveredPayload0));
+        InMemoryJournal.addEntry(leaderId, seqId++, new SimpleReplicatedLogEntry(0, initialTerm, recoveredPayload0));
         recoveredPayload1 = new MockPayload("one");
-        InMemoryJournal.addEntry(leaderId, seqId++, new ReplicatedLogImplEntry(1, initialTerm, recoveredPayload1));
+        InMemoryJournal.addEntry(leaderId, seqId++, new SimpleReplicatedLogEntry(1, initialTerm, recoveredPayload1));
         recoveredPayload2 = new MockPayload("two");
-        InMemoryJournal.addEntry(leaderId, seqId++, new ReplicatedLogImplEntry(2, initialTerm, recoveredPayload2));
+        InMemoryJournal.addEntry(leaderId, seqId++, new SimpleReplicatedLogEntry(2, initialTerm, recoveredPayload2));
         InMemoryJournal.addEntry(leaderId, seqId++, new ApplyJournalEntries(2));
 
-        origLeaderJournal = InMemoryJournal.get(leaderId, ReplicatedLogImplEntry.class);
+        origLeaderJournal = InMemoryJournal.get(leaderId, SimpleReplicatedLogEntry.class);
 
         // Create the leader and 2 follower actors and verify initial syncing of the followers after leader
         // persistence recovery.
@@ -195,8 +196,8 @@ public class ReplicationAndSnapshotsIntegrationTest extends AbstractRaftActorInt
         verifyReplicatedLogEntry(unAppliedEntry.get(0), currentTerm, 3, payload3);
 
         // The leader's persisted journal log should be cleared since we snapshotted.
-        List<ReplicatedLogImplEntry> persistedLeaderJournal =
-                InMemoryJournal.get(leaderId, ReplicatedLogImplEntry.class);
+        List<SimpleReplicatedLogEntry> persistedLeaderJournal =
+                InMemoryJournal.get(leaderId, SimpleReplicatedLogEntry.class);
         assertEquals("Persisted journal log size", 0, persistedLeaderJournal.size());
 
         // Allow AppendEntries to both followers to proceed. This should catch up the followers and cause a
@@ -368,8 +369,8 @@ public class ReplicationAndSnapshotsIntegrationTest extends AbstractRaftActorInt
         verifyReplicatedLogEntry(unAppliedEntry.get(0), currentTerm, 7, payload7);
 
         // The leader's persisted journal log should be cleared since we did a snapshot.
-        List<ReplicatedLogImplEntry> persistedLeaderJournal = InMemoryJournal.get(
-                leaderId, ReplicatedLogImplEntry.class);
+        List<SimpleReplicatedLogEntry> persistedLeaderJournal = InMemoryJournal.get(
+                leaderId, SimpleReplicatedLogEntry.class);
         assertEquals("Persisted journal log size", 0, persistedLeaderJournal.size());
 
         // Verify the followers apply all 4 new log entries.
index b81836e..8a91549 100644 (file)
@@ -36,6 +36,7 @@ import org.opendaylight.controller.cluster.raft.messages.RequestVoteReply;
 import org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries;
 import org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload;
 import org.opendaylight.controller.cluster.raft.persisted.ServerInfo;
+import org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry;
 import org.opendaylight.controller.cluster.raft.persisted.UpdateElectionTerm;
 import org.opendaylight.controller.cluster.raft.utils.InMemoryJournal;
 import org.opendaylight.controller.cluster.raft.utils.InMemorySnapshotStore;
@@ -678,8 +679,8 @@ public class ReplicationAndSnapshotsWithLaggingFollowerIntegrationTest extends A
         // Verify the leaders's persisted journal log - it should only contain the last 2 ReplicatedLogEntries
         // added after the snapshot as the persisted journal should've been purged to the snapshot
         // sequence number.
-        verifyPersistedJournal(leaderId, Arrays.asList(new ReplicatedLogImplEntry(5, currentTerm, payload5),
-                new ReplicatedLogImplEntry(6, currentTerm, payload6)));
+        verifyPersistedJournal(leaderId, Arrays.asList(new SimpleReplicatedLogEntry(5, currentTerm, payload5),
+                new SimpleReplicatedLogEntry(6, currentTerm, payload6)));
 
         // Verify the leaders's persisted journal contains an ApplyJournalEntries for at least the last entry index.
         List<ApplyJournalEntries> persistedApplyJournalEntries =
index 88cb0d3..9cf4015 100644 (file)
@@ -51,7 +51,8 @@ public class SnapshotTest {
     private static Snapshot newLithiumSnapshot() {
         byte[] state = {1, 2, 3, 4, 5};
         List<ReplicatedLogEntry> entries = new ArrayList<>();
-        entries.add(new ReplicatedLogImplEntry(6, 2, new MockPayload("payload")));
+        entries.add(new org.opendaylight.controller.cluster.raft.ReplicatedLogImplEntry(
+                6, 2, new MockPayload("payload")));
         long lastIndex = 6;
         long lastTerm = 2;
         long lastAppliedIndex = 5;
index 4e4fa2c..380a0c2 100644 (file)
@@ -43,7 +43,6 @@ import org.opendaylight.controller.cluster.raft.RaftActorLeadershipTransferCohor
 import org.opendaylight.controller.cluster.raft.RaftState;
 import org.opendaylight.controller.cluster.raft.RaftVersions;
 import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
-import org.opendaylight.controller.cluster.raft.ReplicatedLogImplEntry;
 import org.opendaylight.controller.cluster.raft.Snapshot;
 import org.opendaylight.controller.cluster.raft.VotingState;
 import org.opendaylight.controller.cluster.raft.base.messages.ApplyState;
@@ -60,6 +59,7 @@ import org.opendaylight.controller.cluster.raft.messages.InstallSnapshotReply;
 import org.opendaylight.controller.cluster.raft.messages.RaftRPC;
 import org.opendaylight.controller.cluster.raft.messages.RequestVoteReply;
 import org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries;
+import org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry;
 import org.opendaylight.controller.cluster.raft.policy.DefaultRaftPolicy;
 import org.opendaylight.controller.cluster.raft.policy.RaftPolicy;
 import org.opendaylight.controller.cluster.raft.utils.ForwardMessageToBehaviorActor;
@@ -638,8 +638,8 @@ public class LeaderTest extends AbstractLeaderTest<Leader> {
         MessageCollectorActor.expectFirstMatching(followerActor, AppendEntries.class);
 
         // new entry
-        ReplicatedLogImplEntry entry =
-                new ReplicatedLogImplEntry(newEntryIndex, currentTerm,
+        SimpleReplicatedLogEntry entry =
+                new SimpleReplicatedLogEntry(newEntryIndex, currentTerm,
                         new MockRaftActorContext.MockPayload("D"));
 
         actorContext.getReplicatedLog().append(entry);
@@ -686,7 +686,7 @@ public class LeaderTest extends AbstractLeaderTest<Leader> {
         leader.setSnapshot(null);
 
         // new entry
-        ReplicatedLogImplEntry entry = new ReplicatedLogImplEntry(newEntryIndex, currentTerm,
+        SimpleReplicatedLogEntry entry = new SimpleReplicatedLogEntry(newEntryIndex, currentTerm,
                 new MockRaftActorContext.MockPayload("D"));
 
         actorContext.getReplicatedLog().append(entry);
@@ -742,12 +742,12 @@ public class LeaderTest extends AbstractLeaderTest<Leader> {
         leader.setSnapshot(null);
 
         for (int i = 0; i < 4; i++) {
-            actorContext.getReplicatedLog().append(new ReplicatedLogImplEntry(i, 1,
+            actorContext.getReplicatedLog().append(new SimpleReplicatedLogEntry(i, 1,
                     new MockRaftActorContext.MockPayload("X" + i)));
         }
 
         // new entry
-        ReplicatedLogImplEntry entry = new ReplicatedLogImplEntry(newEntryIndex, currentTerm,
+        SimpleReplicatedLogEntry entry = new SimpleReplicatedLogEntry(newEntryIndex, currentTerm,
                 new MockRaftActorContext.MockPayload("D"));
 
         actorContext.getReplicatedLog().append(entry);
index b7bb741..d6ee614 100644 (file)
@@ -15,7 +15,7 @@ import org.apache.commons.lang.SerializationUtils;
 import org.junit.Test;
 import org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload;
 import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
-import org.opendaylight.controller.cluster.raft.ReplicatedLogImplEntry;
+import org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry;
 
 /**
  * Unit tests for AppendEntries.
@@ -26,9 +26,9 @@ public class AppendEntriesTest {
 
     @Test
     public void testSerialization() {
-        ReplicatedLogEntry entry1 = new ReplicatedLogImplEntry(1, 2, new MockPayload("payload1"));
+        ReplicatedLogEntry entry1 = new SimpleReplicatedLogEntry(1, 2, new MockPayload("payload1"));
 
-        ReplicatedLogEntry entry2 = new ReplicatedLogImplEntry(3, 4, new MockPayload("payload2"));
+        ReplicatedLogEntry entry2 = new SimpleReplicatedLogEntry(3, 4, new MockPayload("payload2"));
 
         short payloadVersion = 5;
         AppendEntries expected = new AppendEntries(5L, "node1", 7L, 8L, Arrays.asList(entry1, entry2), 10L,
diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/persisted/SimpleReplicatedLogEntryTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/persisted/SimpleReplicatedLogEntryTest.java
new file mode 100644 (file)
index 0000000..93c313a
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016 2015 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.raft.persisted;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.commons.lang.SerializationUtils;
+import org.junit.Test;
+import org.opendaylight.controller.cluster.raft.MockRaftActorContext;
+
+/**
+ * Unit tests for SimpleReplicatedLogEntry.
+ *
+ * @author Thomas Pantelis
+ */
+public class SimpleReplicatedLogEntryTest {
+
+    @Test
+    public void testSerialization() {
+        SimpleReplicatedLogEntry expected = new SimpleReplicatedLogEntry(0, 1,
+                new MockRaftActorContext.MockPayload("A"));
+        SimpleReplicatedLogEntry cloned = (SimpleReplicatedLogEntry) SerializationUtils.clone(expected);
+
+        assertEquals("getTerm", expected.getTerm(), cloned.getTerm());
+        assertEquals("getIndex", expected.getIndex(), cloned.getIndex());
+        assertEquals("getData", expected.getData(), cloned.getData());
+        assertEquals("isMigrated", false, cloned.isMigrated());
+    }
+}
index 8310e06..0a392bf 100644 (file)
@@ -87,7 +87,6 @@ import org.opendaylight.controller.cluster.notifications.RegisterRoleChangeListe
 import org.opendaylight.controller.cluster.notifications.RegisterRoleChangeListenerReply;
 import org.opendaylight.controller.cluster.raft.RaftActorContext;
 import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
-import org.opendaylight.controller.cluster.raft.ReplicatedLogImplEntry;
 import org.opendaylight.controller.cluster.raft.Snapshot;
 import org.opendaylight.controller.cluster.raft.base.messages.ApplySnapshot;
 import org.opendaylight.controller.cluster.raft.base.messages.ApplyState;
@@ -101,6 +100,7 @@ import org.opendaylight.controller.cluster.raft.client.messages.OnDemandRaftStat
 import org.opendaylight.controller.cluster.raft.messages.RequestVote;
 import org.opendaylight.controller.cluster.raft.messages.ServerRemoved;
 import org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries;
+import org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry;
 import org.opendaylight.controller.cluster.raft.policy.DisableElectionsRaftPolicy;
 import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
 import org.opendaylight.controller.cluster.raft.utils.InMemoryJournal;
@@ -490,7 +490,7 @@ public class ShardTest extends AbstractShardTest {
 
         final TransactionIdentifier tx = nextTransactionId();
         final ApplyState applyState = new ApplyState(null, tx,
-                new ReplicatedLogImplEntry(1, 2, payloadForModification(store, writeMod, tx)));
+                new SimpleReplicatedLogEntry(1, 2, payloadForModification(store, writeMod, tx)));
 
         shard.tell(applyState, shard);
 
@@ -519,7 +519,7 @@ public class ShardTest extends AbstractShardTest {
         InMemoryJournal.addEntry(shardID.toString(), 0, DUMMY_DATA);
 
         // Set up the InMemoryJournal.
-        InMemoryJournal.addEntry(shardID.toString(), 1, new ReplicatedLogImplEntry(0, 1,
+        InMemoryJournal.addEntry(shardID.toString(), 1, new SimpleReplicatedLogEntry(0, 1,
             payloadForModification(source, writeMod, nextTransactionId())));
 
         final int nListEntries = 16;
@@ -536,7 +536,7 @@ public class ShardTest extends AbstractShardTest {
             mod.merge(path, ImmutableNodes.mapEntry(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, i));
             mod.ready();
 
-            InMemoryJournal.addEntry(shardID.toString(), i + 1, new ReplicatedLogImplEntry(i, 1,
+            InMemoryJournal.addEntry(shardID.toString(), i + 1, new SimpleReplicatedLogEntry(i, 1,
                 payloadForModification(source, mod, nextTransactionId())));
         }
 

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.