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 public class Snapshot implements Serializable {
28 * Implementations of this interface are used as the state payload for a snapshot.
30 * @author Thomas Pantelis
32 public interface State extends Serializable {
35 private static final class Proxy implements Externalizable {
36 private static final long serialVersionUID = 1L;
38 private Snapshot snapshot;
40 // checkstyle flags the public modifier as redundant which really doesn't make sense since it clearly isn't
41 // redundant. It is explicitly needed for Java serialization to be able to create instances via reflection.
42 @SuppressWarnings("checkstyle:RedundantModifier")
47 Proxy(final Snapshot snapshot) {
48 this.snapshot = snapshot;
52 public void writeExternal(final ObjectOutput out) throws IOException {
53 out.writeLong(snapshot.lastIndex);
54 out.writeLong(snapshot.lastTerm);
55 out.writeLong(snapshot.lastAppliedIndex);
56 out.writeLong(snapshot.lastAppliedTerm);
57 out.writeLong(snapshot.electionTerm);
58 out.writeObject(snapshot.electionVotedFor);
59 out.writeObject(snapshot.serverConfig);
61 out.writeInt(snapshot.unAppliedEntries.size());
62 for (ReplicatedLogEntry e: snapshot.unAppliedEntries) {
63 out.writeLong(e.getIndex());
64 out.writeLong(e.getTerm());
65 out.writeObject(e.getData());
68 out.writeObject(snapshot.state);
72 public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
73 long lastIndex = in.readLong();
74 long lastTerm = in.readLong();
75 long lastAppliedIndex = in.readLong();
76 long lastAppliedTerm = in.readLong();
77 long electionTerm = in.readLong();
78 String electionVotedFor = (String) in.readObject();
79 ServerConfigurationPayload serverConfig = (ServerConfigurationPayload) in.readObject();
81 int size = in.readInt();
82 List<ReplicatedLogEntry> unAppliedEntries = new ArrayList<>(size);
83 for (int i = 0; i < size; i++) {
84 unAppliedEntries.add(new SimpleReplicatedLogEntry(in.readLong(), in.readLong(),
85 (Payload) in.readObject()));
88 State state = (State) in.readObject();
90 snapshot = Snapshot.create(state, unAppliedEntries, lastIndex, lastTerm, lastAppliedIndex, lastAppliedTerm,
91 electionTerm, electionVotedFor, serverConfig);
94 private Object readResolve() {
99 private static final long serialVersionUID = 1L;
101 private final State state;
102 private final List<ReplicatedLogEntry> unAppliedEntries;
103 private final long lastIndex;
104 private final long lastTerm;
105 private final long lastAppliedIndex;
106 private final long lastAppliedTerm;
107 private final long electionTerm;
108 private final String electionVotedFor;
109 private final ServerConfigurationPayload serverConfig;
111 private Snapshot(State state, List<ReplicatedLogEntry> unAppliedEntries, long lastIndex, long lastTerm,
112 long lastAppliedIndex, long lastAppliedTerm, long electionTerm, String electionVotedFor,
113 ServerConfigurationPayload serverConfig) {
115 this.unAppliedEntries = unAppliedEntries;
116 this.lastIndex = lastIndex;
117 this.lastTerm = lastTerm;
118 this.lastAppliedIndex = lastAppliedIndex;
119 this.lastAppliedTerm = lastAppliedTerm;
120 this.electionTerm = electionTerm;
121 this.electionVotedFor = electionVotedFor;
122 this.serverConfig = serverConfig;
125 public static Snapshot create(State state, List<ReplicatedLogEntry> entries, long lastIndex, long lastTerm,
126 long lastAppliedIndex, long lastAppliedTerm, long electionTerm, String electionVotedFor,
127 ServerConfigurationPayload serverConfig) {
128 return new Snapshot(state, entries, lastIndex, lastTerm, lastAppliedIndex, lastAppliedTerm,
129 electionTerm, electionVotedFor, serverConfig);
132 public State getState() {
136 public List<ReplicatedLogEntry> getUnAppliedEntries() {
137 return unAppliedEntries;
140 public long getLastTerm() {
144 public long getLastAppliedIndex() {
145 return lastAppliedIndex;
148 public long getLastAppliedTerm() {
149 return lastAppliedTerm;
152 public long getLastIndex() {
153 return this.lastIndex;
156 public long getElectionTerm() {
160 public String getElectionVotedFor() {
161 return electionVotedFor;
164 public ServerConfigurationPayload getServerConfiguration() {
168 @SuppressWarnings("static-method")
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 + "]";