2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.cluster.raft.persisted;
10 import java.io.Externalizable;
11 import java.io.IOException;
12 import java.io.ObjectInput;
13 import java.io.ObjectOutput;
14 import java.io.Serializable;
15 import java.util.ArrayList;
16 import java.util.List;
17 import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
18 import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
21 * Represents a snapshot of the raft data.
23 * @author Thomas Pantelis
25 // Not final for mocking
26 public class Snapshot implements Serializable {
29 * Implementations of this interface are used as the state payload for a snapshot.
31 * @author Thomas Pantelis
33 public interface State extends Serializable {
36 private static final class Proxy implements Externalizable {
37 private static final long serialVersionUID = 1L;
39 private Snapshot snapshot;
41 // checkstyle flags the public modifier as redundant which really doesn't make sense since it clearly isn't
42 // redundant. It is explicitly needed for Java serialization to be able to create instances via reflection.
43 @SuppressWarnings("checkstyle:RedundantModifier")
48 Proxy(final Snapshot snapshot) {
49 this.snapshot = snapshot;
53 public void writeExternal(final ObjectOutput out) throws IOException {
54 out.writeLong(snapshot.lastIndex);
55 out.writeLong(snapshot.lastTerm);
56 out.writeLong(snapshot.lastAppliedIndex);
57 out.writeLong(snapshot.lastAppliedTerm);
58 out.writeLong(snapshot.electionTerm);
59 out.writeObject(snapshot.electionVotedFor);
60 out.writeObject(snapshot.serverConfig);
62 out.writeInt(snapshot.unAppliedEntries.size());
63 for (ReplicatedLogEntry e: snapshot.unAppliedEntries) {
64 out.writeLong(e.getIndex());
65 out.writeLong(e.getTerm());
66 out.writeObject(e.getData());
69 out.writeObject(snapshot.state);
73 public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
74 long lastIndex = in.readLong();
75 long lastTerm = in.readLong();
76 long lastAppliedIndex = in.readLong();
77 long lastAppliedTerm = in.readLong();
78 long electionTerm = in.readLong();
79 String electionVotedFor = (String) in.readObject();
80 ServerConfigurationPayload serverConfig = (ServerConfigurationPayload) in.readObject();
82 int size = in.readInt();
83 List<ReplicatedLogEntry> unAppliedEntries = new ArrayList<>(size);
84 for (int i = 0; i < size; i++) {
85 unAppliedEntries.add(new SimpleReplicatedLogEntry(in.readLong(), in.readLong(),
86 (Payload) in.readObject()));
89 State state = (State) in.readObject();
91 snapshot = Snapshot.create(state, unAppliedEntries, lastIndex, lastTerm, lastAppliedIndex, lastAppliedTerm,
92 electionTerm, electionVotedFor, serverConfig);
95 private Object readResolve() {
100 private static final long serialVersionUID = 1L;
102 private final State state;
103 private final List<ReplicatedLogEntry> unAppliedEntries;
104 private final long lastIndex;
105 private final long lastTerm;
106 private final long lastAppliedIndex;
107 private final long lastAppliedTerm;
108 private final long electionTerm;
109 private final String electionVotedFor;
110 private final ServerConfigurationPayload serverConfig;
112 Snapshot(final State state, final List<ReplicatedLogEntry> unAppliedEntries, final long lastIndex,
113 final long lastTerm, final long lastAppliedIndex, final long lastAppliedTerm, final long electionTerm,
114 final String electionVotedFor, final ServerConfigurationPayload serverConfig) {
116 this.unAppliedEntries = unAppliedEntries;
117 this.lastIndex = lastIndex;
118 this.lastTerm = lastTerm;
119 this.lastAppliedIndex = lastAppliedIndex;
120 this.lastAppliedTerm = lastAppliedTerm;
121 this.electionTerm = electionTerm;
122 this.electionVotedFor = electionVotedFor;
123 this.serverConfig = serverConfig;
126 public static Snapshot create(final State state, final List<ReplicatedLogEntry> entries, final long lastIndex,
127 final long lastTerm, final long lastAppliedIndex, final long lastAppliedTerm, final long electionTerm,
128 final String electionVotedFor, final ServerConfigurationPayload serverConfig) {
129 return new Snapshot(state, entries, lastIndex, lastTerm, lastAppliedIndex, lastAppliedTerm,
130 electionTerm, electionVotedFor, serverConfig);
133 public State getState() {
137 public List<ReplicatedLogEntry> getUnAppliedEntries() {
138 return unAppliedEntries;
141 public long getLastTerm() {
145 public long getLastAppliedIndex() {
146 return lastAppliedIndex;
149 public long getLastAppliedTerm() {
150 return lastAppliedTerm;
153 public long getLastIndex() {
154 return this.lastIndex;
157 public long getElectionTerm() {
161 public String getElectionVotedFor() {
162 return electionVotedFor;
165 public ServerConfigurationPayload getServerConfiguration() {
169 private Object writeReplace() {
170 return new Proxy(this);
174 public String toString() {
175 return "Snapshot [lastIndex=" + lastIndex + ", lastTerm=" + lastTerm + ", lastAppliedIndex=" + lastAppliedIndex
176 + ", lastAppliedTerm=" + lastAppliedTerm + ", unAppliedEntries size=" + unAppliedEntries.size()
177 + ", state=" + state + ", electionTerm=" + electionTerm + ", electionVotedFor="
178 + electionVotedFor + ", ServerConfigPayload=" + serverConfig + "]";