42a4a8de810bd5a2b4d04d872b2e00620ff9bd07
[controller.git] / opendaylight / md-sal / sal-akka-raft / src / main / java / org / opendaylight / controller / cluster / raft / persisted / Snapshot.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.controller.cluster.raft.persisted;
9
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;
19
20 /**
21  * Represents a snapshot of the raft data.
22  *
23  * @author Thomas Pantelis
24  */
25 // Not final for mocking
26 public class Snapshot implements Serializable {
27
28     /**
29      * Implementations of this interface are used as the state payload for a snapshot.
30      *
31      * @author Thomas Pantelis
32      */
33     public interface State extends Serializable {
34     }
35
36     private static final class Proxy implements Externalizable {
37         private static final long serialVersionUID = 1L;
38
39         private Snapshot snapshot;
40
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")
44         public Proxy() {
45             // For Externalizable
46         }
47
48         Proxy(final Snapshot snapshot) {
49             this.snapshot = snapshot;
50         }
51
52         @Override
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);
61
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());
67             }
68
69             out.writeObject(snapshot.state);
70         }
71
72         @Override
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();
81
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()));
87             }
88
89             State state = (State) in.readObject();
90
91             snapshot = Snapshot.create(state, unAppliedEntries, lastIndex, lastTerm, lastAppliedIndex, lastAppliedTerm,
92                     electionTerm, electionVotedFor, serverConfig);
93         }
94
95         private Object readResolve() {
96             return snapshot;
97         }
98     }
99
100     private static final long serialVersionUID = 1L;
101
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;
111
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) {
115         this.state = state;
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;
124     }
125
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);
131     }
132
133     public State getState() {
134         return state;
135     }
136
137     public List<ReplicatedLogEntry> getUnAppliedEntries() {
138         return unAppliedEntries;
139     }
140
141     public long getLastTerm() {
142         return lastTerm;
143     }
144
145     public long getLastAppliedIndex() {
146         return lastAppliedIndex;
147     }
148
149     public long getLastAppliedTerm() {
150         return lastAppliedTerm;
151     }
152
153     public long getLastIndex() {
154         return this.lastIndex;
155     }
156
157     public long getElectionTerm() {
158         return electionTerm;
159     }
160
161     public String getElectionVotedFor() {
162         return electionVotedFor;
163     }
164
165     public ServerConfigurationPayload getServerConfiguration() {
166         return serverConfig;
167     }
168
169     private Object writeReplace() {
170         return new Proxy(this);
171     }
172
173     @Override
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 + "]";
179     }
180 }