Merge "Make Raft messages serializable"
[controller.git] / opendaylight / md-sal / sal-akka-raft / src / test / java / org / opendaylight / controller / cluster / raft / MockRaftActorContext.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
9 package org.opendaylight.controller.cluster.raft;
10
11 import akka.actor.ActorRef;
12 import akka.actor.ActorSelection;
13 import akka.actor.ActorSystem;
14 import akka.actor.Props;
15 import akka.event.Logging;
16 import akka.event.LoggingAdapter;
17 import com.google.protobuf.GeneratedMessage;
18 import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
19 import org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages;
20 import org.opendaylight.controller.cluster.raft.protobuff.messages.MockPayloadMessages;
21
22 import java.io.Serializable;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28
29 public class MockRaftActorContext implements RaftActorContext {
30
31     private String id;
32     private ActorSystem system;
33     private ActorRef actor;
34     private long index = 0;
35     private long lastApplied = 0;
36     private final ElectionTerm electionTerm;
37     private ReplicatedLog replicatedLog;
38     private Map<String, String> peerAddresses = new HashMap();
39
40     public MockRaftActorContext(){
41         electionTerm = null;
42
43         initReplicatedLog();
44     }
45
46     public MockRaftActorContext(String id, ActorSystem system, ActorRef actor){
47         this.id = id;
48         this.system = system;
49         this.actor = actor;
50
51         final String id1 = id;
52         electionTerm = new ElectionTerm() {
53             /**
54              * Identifier of the actor whose election term information this is
55              */
56             private final String id = id1;
57             private long currentTerm = 0;
58             private String votedFor = "";
59
60             public long getCurrentTerm() {
61                 return currentTerm;
62             }
63
64             public String getVotedFor() {
65                 return votedFor;
66             }
67
68             public void update(long currentTerm, String votedFor){
69                 this.currentTerm = currentTerm;
70                 this.votedFor = votedFor;
71
72                 // TODO : Write to some persistent state
73             }
74
75             @Override public void updateAndPersist(long currentTerm,
76                 String votedFor) {
77                 update(currentTerm, votedFor);
78             }
79         };
80
81         initReplicatedLog();
82     }
83
84
85     public void initReplicatedLog(){
86         this.replicatedLog = new SimpleReplicatedLog();
87         this.replicatedLog.append(new MockReplicatedLogEntry(1, 1, new MockPayload("")));
88     }
89
90     @Override public ActorRef actorOf(Props props) {
91         return system.actorOf(props);
92     }
93
94     @Override public ActorSelection actorSelection(String path) {
95         return system.actorSelection(path);
96     }
97
98     @Override public String getId() {
99         return id;
100     }
101
102     @Override public ActorRef getActor() {
103         return actor;
104     }
105
106     @Override public ElectionTerm getTermInformation() {
107         return electionTerm;
108     }
109
110     public void setIndex(long index){
111         this.index = index;
112     }
113
114     @Override public long getCommitIndex() {
115         return index;
116     }
117
118     @Override public void setCommitIndex(long commitIndex) {
119         this.index = commitIndex;
120     }
121
122     @Override public void setLastApplied(long lastApplied){
123         this.lastApplied = lastApplied;
124     }
125
126     @Override public long getLastApplied() {
127         return lastApplied;
128     }
129
130     public void setReplicatedLog(ReplicatedLog replicatedLog) {
131         this.replicatedLog = replicatedLog;
132     }
133
134     @Override public ReplicatedLog getReplicatedLog() {
135         return replicatedLog;
136     }
137
138     @Override public ActorSystem getActorSystem() {
139         return this.system;
140     }
141
142     @Override public LoggingAdapter getLogger() {
143         return Logging.getLogger(system, this);
144     }
145
146     @Override public Map<String, String> getPeerAddresses() {
147         return peerAddresses;
148     }
149
150     @Override public String getPeerAddress(String peerId) {
151         return peerAddresses.get(peerId);
152     }
153
154     @Override public void addToPeers(String name, String address) {
155         peerAddresses.put(name, address);
156     }
157
158     @Override public void removePeer(String name) {
159         peerAddresses.remove(name);
160     }
161
162     public void setPeerAddresses(Map<String, String> peerAddresses) {
163         this.peerAddresses = peerAddresses;
164     }
165
166
167
168     public static class SimpleReplicatedLog implements ReplicatedLog {
169         private final List<ReplicatedLogEntry> log = new ArrayList<>();
170
171         @Override public ReplicatedLogEntry get(long index) {
172             if(index >= log.size() || index < 0){
173                 return null;
174             }
175             return log.get((int) index);
176         }
177
178         @Override public ReplicatedLogEntry last() {
179             if(log.size() == 0){
180                 return null;
181             }
182             return log.get(log.size()-1);
183         }
184
185         @Override public long lastIndex() {
186             if(log.size() == 0){
187                 return -1;
188             }
189
190             return last().getIndex();
191         }
192
193         @Override public long lastTerm() {
194             if(log.size() == 0){
195                 return -1;
196             }
197
198             return last().getTerm();
199         }
200
201         @Override public void removeFrom(long index) {
202             if(index >= log.size() || index < 0){
203                 return;
204             }
205
206             log.subList((int) index, log.size()).clear();
207             //log.remove((int) index);
208         }
209
210         @Override public void removeFromAndPersist(long index) {
211             removeFrom(index);
212         }
213
214         @Override public void append(ReplicatedLogEntry replicatedLogEntry) {
215             log.add(replicatedLogEntry);
216         }
217
218         @Override public void appendAndPersist(
219             ReplicatedLogEntry replicatedLogEntry) {
220             append(replicatedLogEntry);
221         }
222
223         @Override public List<ReplicatedLogEntry> getFrom(long index) {
224             if(index >= log.size() || index < 0){
225                 return Collections.EMPTY_LIST;
226             }
227             List<ReplicatedLogEntry> entries = new ArrayList<>();
228             for(int i=(int) index ; i < log.size() ; i++) {
229                 entries.add(get(i));
230             }
231             return entries;
232         }
233
234         @Override public long size() {
235             return log.size();
236         }
237
238         @Override public boolean isPresent(long index) {
239             if(index >= log.size() || index < 0){
240                 return false;
241             }
242
243             return true;
244         }
245
246         @Override public boolean isInSnapshot(long index) {
247             return false;
248         }
249
250         @Override public Object getSnapshot() {
251             return null;
252         }
253
254         @Override public long getSnapshotIndex() {
255             return -1;
256         }
257
258         @Override public long getSnapshotTerm() {
259             return -1;
260         }
261     }
262
263     public static class MockPayload extends Payload implements Serializable {
264         private String value = "";
265
266         public MockPayload(String s) {
267             this.value = s;
268         }
269
270         @Override public  Map<GeneratedMessage.GeneratedExtension, String> encode() {
271             Map<GeneratedMessage.GeneratedExtension, String> map = new HashMap<GeneratedMessage.GeneratedExtension, String>();
272             map.put(MockPayloadMessages.value, value);
273             return map;
274         }
275
276         @Override public Payload decode(
277             AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload payloadProtoBuff) {
278             String value = payloadProtoBuff.getExtension(MockPayloadMessages.value);
279             this.value = value;
280             return this;
281         }
282
283         @Override public String getClientPayloadClassName() {
284             return MockPayload.class.getName();
285         }
286
287         public String toString() {
288             return value;
289         }
290     }
291
292     public static class MockReplicatedLogEntry implements ReplicatedLogEntry, Serializable {
293
294         private final long term;
295         private final long index;
296         private final Payload data;
297
298         public MockReplicatedLogEntry(long term, long index, Payload data){
299
300             this.term = term;
301             this.index = index;
302             this.data = data;
303         }
304
305         @Override public Payload getData() {
306             return data;
307         }
308
309         @Override public long getTerm() {
310             return term;
311         }
312
313         @Override public long getIndex() {
314             return index;
315         }
316     }
317 }