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