Switch to ARGON raft version
[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.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          * Indicate whether the snapshot requires migration, i.e. a new snapshot should be created after recovery.
36          * Default implementation returns false, i.e. do not re-snapshot.
37          *
38          * @return True if complete recovery based upon this snapshot should trigger a new snapshot.
39          */
40         default boolean needsMigration() {
41             return false;
42         }
43     }
44
45     @Deprecated(since = "7.0.0", forRemoval = true)
46     private static final class Proxy implements Externalizable {
47         @java.io.Serial
48         private static final long serialVersionUID = 1L;
49
50         private Snapshot snapshot;
51
52         // checkstyle flags the public modifier as redundant which really doesn't make sense since it clearly isn't
53         // redundant. It is explicitly needed for Java serialization to be able to create instances via reflection.
54         @SuppressWarnings("checkstyle:RedundantModifier")
55         public Proxy() {
56             // For Externalizable
57         }
58
59         Proxy(final Snapshot snapshot) {
60             this.snapshot = snapshot;
61         }
62
63         @Override
64         public void writeExternal(final ObjectOutput out) throws IOException {
65             out.writeLong(snapshot.lastIndex);
66             out.writeLong(snapshot.lastTerm);
67             out.writeLong(snapshot.lastAppliedIndex);
68             out.writeLong(snapshot.lastAppliedTerm);
69             out.writeLong(snapshot.electionTerm);
70             out.writeObject(snapshot.electionVotedFor);
71             out.writeObject(snapshot.serverConfig);
72
73             out.writeInt(snapshot.unAppliedEntries.size());
74             for (ReplicatedLogEntry e: snapshot.unAppliedEntries) {
75                 out.writeLong(e.getIndex());
76                 out.writeLong(e.getTerm());
77                 out.writeObject(e.getData());
78             }
79
80             out.writeObject(snapshot.state);
81         }
82
83         @Override
84         public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
85             long lastIndex = in.readLong();
86             long lastTerm = in.readLong();
87             long lastAppliedIndex = in.readLong();
88             long lastAppliedTerm = in.readLong();
89             long electionTerm = in.readLong();
90             String electionVotedFor = (String) in.readObject();
91             ServerConfigurationPayload serverConfig = (ServerConfigurationPayload) in.readObject();
92
93             int size = in.readInt();
94             List<ReplicatedLogEntry> unAppliedEntries = new ArrayList<>(size);
95             for (int i = 0; i < size; i++) {
96                 unAppliedEntries.add(new SimpleReplicatedLogEntry(in.readLong(), in.readLong(),
97                         (Payload) in.readObject()));
98             }
99
100             State state = (State) in.readObject();
101
102             snapshot = Snapshot.create(state, unAppliedEntries, lastIndex, lastTerm, lastAppliedIndex, lastAppliedTerm,
103                     electionTerm, electionVotedFor, serverConfig);
104         }
105
106         @java.io.Serial
107         private Object readResolve() {
108             return snapshot;
109         }
110     }
111
112     @java.io.Serial
113     private static final long serialVersionUID = 1L;
114
115     private final State state;
116     private final List<ReplicatedLogEntry> unAppliedEntries;
117     private final long lastIndex;
118     private final long lastTerm;
119     private final long lastAppliedIndex;
120     private final long lastAppliedTerm;
121     private final long electionTerm;
122     private final String electionVotedFor;
123     private final ServerConfigurationPayload serverConfig;
124
125     Snapshot(final State state, final List<ReplicatedLogEntry> unAppliedEntries, final long lastIndex,
126             final long lastTerm, final long lastAppliedIndex, final long lastAppliedTerm, final long electionTerm,
127             final String electionVotedFor, final ServerConfigurationPayload serverConfig) {
128         this.state = state;
129         this.unAppliedEntries = unAppliedEntries;
130         this.lastIndex = lastIndex;
131         this.lastTerm = lastTerm;
132         this.lastAppliedIndex = lastAppliedIndex;
133         this.lastAppliedTerm = lastAppliedTerm;
134         this.electionTerm = electionTerm;
135         this.electionVotedFor = electionVotedFor;
136         this.serverConfig = serverConfig;
137     }
138
139     public static Snapshot create(final State state, final List<ReplicatedLogEntry> entries, final long lastIndex,
140             final long lastTerm, final long lastAppliedIndex, final long lastAppliedTerm, final long electionTerm,
141             final String electionVotedFor, final ServerConfigurationPayload serverConfig) {
142         return new Snapshot(state, entries, lastIndex, lastTerm, lastAppliedIndex, lastAppliedTerm,
143                 electionTerm, electionVotedFor, serverConfig);
144     }
145
146     public State getState() {
147         return state;
148     }
149
150     public List<ReplicatedLogEntry> getUnAppliedEntries() {
151         return unAppliedEntries;
152     }
153
154     public long getLastTerm() {
155         return lastTerm;
156     }
157
158     public long getLastAppliedIndex() {
159         return lastAppliedIndex;
160     }
161
162     public long getLastAppliedTerm() {
163         return lastAppliedTerm;
164     }
165
166     public long getLastIndex() {
167         return lastIndex;
168     }
169
170     public long getElectionTerm() {
171         return electionTerm;
172     }
173
174     public String getElectionVotedFor() {
175         return electionVotedFor;
176     }
177
178     public ServerConfigurationPayload getServerConfiguration() {
179         return serverConfig;
180     }
181
182     @java.io.Serial
183     private Object writeReplace() {
184         return new SS(this);
185     }
186
187     @Override
188     public String toString() {
189         return "Snapshot [lastIndex=" + lastIndex + ", lastTerm=" + lastTerm + ", lastAppliedIndex=" + lastAppliedIndex
190                 + ", lastAppliedTerm=" + lastAppliedTerm + ", unAppliedEntries size=" + unAppliedEntries.size()
191                 + ", state=" + state + ", electionTerm=" + electionTerm + ", electionVotedFor="
192                 + electionVotedFor + ", ServerConfigPayload="  + serverConfig + "]";
193     }
194 }