5a4b43721db99d1d2a548afceb00bcc47b7f37d8
[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.japi.Procedure;
16 import java.io.Serializable;
17 import java.util.HashMap;
18 import java.util.Map;
19 import org.opendaylight.controller.cluster.NonPersistentDataProvider;
20 import org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior;
21 import org.opendaylight.controller.cluster.raft.policy.RaftPolicy;
22 import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 public class MockRaftActorContext extends RaftActorContextImpl {
27     private static final Logger LOG = LoggerFactory.getLogger(MockRaftActorContext.class);
28
29     private ActorSystem system;
30     private RaftPolicy raftPolicy;
31
32     private static ElectionTerm newElectionTerm() {
33         return new ElectionTerm() {
34             private long currentTerm = 1;
35             private String votedFor = "";
36
37             @Override
38             public long getCurrentTerm() {
39                 return currentTerm;
40             }
41
42             @Override
43             public String getVotedFor() {
44                 return votedFor;
45             }
46
47             @Override
48             public void update(long currentTerm, String votedFor){
49                 this.currentTerm = currentTerm;
50                 this.votedFor = votedFor;
51
52                 // TODO : Write to some persistent state
53             }
54
55             @Override public void updateAndPersist(long currentTerm,
56                 String votedFor) {
57                 update(currentTerm, votedFor);
58             }
59         };
60     }
61
62     public MockRaftActorContext(){
63         super(null, null, "test", newElectionTerm(), -1, -1, new HashMap<String, String>(),
64                 new DefaultConfigParamsImpl(), new NonPersistentDataProvider(), LOG);
65         setReplicatedLog(new MockReplicatedLogBuilder().build());
66     }
67
68     public MockRaftActorContext(String id, ActorSystem system, ActorRef actor){
69         super(actor, null, id, newElectionTerm(), -1, -1, new HashMap<String, String>(),
70                 new DefaultConfigParamsImpl(), new NonPersistentDataProvider(), LOG);
71
72         this.system = system;
73
74         initReplicatedLog();
75     }
76
77
78     public void initReplicatedLog(){
79         SimpleReplicatedLog replicatedLog = new SimpleReplicatedLog();
80         long term = getTermInformation().getCurrentTerm();
81         replicatedLog.append(new MockReplicatedLogEntry(term, 0, new MockPayload("1")));
82         replicatedLog.append(new MockReplicatedLogEntry(term, 1, new MockPayload("2")));
83         setReplicatedLog(replicatedLog);
84     }
85
86     @Override public ActorRef actorOf(Props props) {
87         return system.actorOf(props);
88     }
89
90     @Override public ActorSelection actorSelection(String path) {
91         return system.actorSelection(path);
92     }
93
94     @Override public ActorSystem getActorSystem() {
95         return this.system;
96     }
97
98     @Override public ActorSelection getPeerActorSelection(String peerId) {
99         String peerAddress = getPeerAddress(peerId);
100         if(peerAddress != null){
101             return actorSelection(peerAddress);
102         }
103         return null;
104     }
105
106     public void setPeerAddresses(Map<String, String> peerAddresses) {
107         for(String id: getPeerIds()) {
108             removePeer(id);
109         }
110
111         for(Map.Entry<String, String> e: peerAddresses.entrySet()) {
112             addToPeers(e.getKey(), e.getValue(), VotingState.VOTING);
113         }
114     }
115
116     @Override
117     public SnapshotManager getSnapshotManager() {
118         SnapshotManager snapshotManager = super.getSnapshotManager();
119         snapshotManager.setCreateSnapshotRunnable(() -> { });
120         return snapshotManager;
121     }
122
123     @Override
124     public RaftPolicy getRaftPolicy() {
125         return raftPolicy != null ? raftPolicy : super.getRaftPolicy();
126     }
127
128     public void setRaftPolicy(RaftPolicy raftPolicy) {
129         this.raftPolicy = raftPolicy;
130     }
131
132     public static class SimpleReplicatedLog extends AbstractReplicatedLogImpl {
133         @Override
134         public void appendAndPersist(
135             ReplicatedLogEntry replicatedLogEntry) {
136             append(replicatedLogEntry);
137         }
138
139         @Override
140         public int dataSize() {
141             return -1;
142         }
143
144         @Override
145         public void captureSnapshotIfReady(ReplicatedLogEntry replicatedLogEntry) {
146         }
147
148         @Override
149         public boolean removeFromAndPersist(long index) {
150             return removeFrom(index) >= 0;
151         }
152
153         @Override
154         public void appendAndPersist(ReplicatedLogEntry replicatedLogEntry, Procedure<ReplicatedLogEntry> callback) {
155             append(replicatedLogEntry);
156
157             if(callback != null) {
158                 try {
159                     callback.apply(replicatedLogEntry);
160                 } catch (Exception e) {
161                     e.printStackTrace();
162                 }
163             }
164         }
165     }
166
167     public static class MockPayload extends Payload implements Serializable {
168         private static final long serialVersionUID = 3121380393130864247L;
169         private String value = "";
170         private int size;
171
172         public MockPayload() {
173         }
174
175         public MockPayload(String s) {
176             this.value = s;
177             size = value.length();
178         }
179
180         public MockPayload(String s, int size) {
181             this(s);
182             this.size = size;
183         }
184
185         @Override
186         public int size() {
187             return size;
188         }
189
190         @Override
191         public String toString() {
192             return value;
193         }
194
195         @Override
196         public int hashCode() {
197             final int prime = 31;
198             int result = 1;
199             result = prime * result + ((value == null) ? 0 : value.hashCode());
200             return result;
201         }
202
203         @Override
204         public boolean equals(Object obj) {
205             if (this == obj) {
206                 return true;
207             }
208             if (obj == null) {
209                 return false;
210             }
211             if (getClass() != obj.getClass()) {
212                 return false;
213             }
214             MockPayload other = (MockPayload) obj;
215             if (value == null) {
216                 if (other.value != null) {
217                     return false;
218                 }
219             } else if (!value.equals(other.value)) {
220                 return false;
221             }
222             return true;
223         }
224     }
225
226     public static class MockReplicatedLogEntry implements ReplicatedLogEntry, Serializable {
227         private static final long serialVersionUID = 1L;
228
229         private final long term;
230         private final long index;
231         private final Payload data;
232
233         public MockReplicatedLogEntry(long term, long index, Payload data){
234
235             this.term = term;
236             this.index = index;
237             this.data = data;
238         }
239
240         @Override public Payload getData() {
241             return data;
242         }
243
244         @Override public long getTerm() {
245             return term;
246         }
247
248         @Override public long getIndex() {
249             return index;
250         }
251
252         @Override
253         public int size() {
254             return getData().size();
255         }
256
257         @Override
258         public int hashCode() {
259             final int prime = 31;
260             int result = 1;
261             result = prime * result + ((data == null) ? 0 : data.hashCode());
262             result = prime * result + (int) (index ^ (index >>> 32));
263             result = prime * result + (int) (term ^ (term >>> 32));
264             return result;
265         }
266
267         @Override
268         public boolean equals(Object obj) {
269             if (this == obj) {
270                 return true;
271             }
272             if (obj == null) {
273                 return false;
274             }
275             if (getClass() != obj.getClass()) {
276                 return false;
277             }
278             MockReplicatedLogEntry other = (MockReplicatedLogEntry) obj;
279             if (data == null) {
280                 if (other.data != null) {
281                     return false;
282                 }
283             } else if (!data.equals(other.data)) {
284                 return false;
285             }
286             if (index != other.index) {
287                 return false;
288             }
289             if (term != other.term) {
290                 return false;
291             }
292             return true;
293         }
294
295         @Override
296         public String toString() {
297             StringBuilder builder = new StringBuilder();
298             builder.append("MockReplicatedLogEntry [term=").append(term).append(", index=").append(index)
299                     .append(", data=").append(data).append("]");
300             return builder.toString();
301         }
302     }
303
304     public static class MockReplicatedLogBuilder {
305         private final ReplicatedLog mockLog = new SimpleReplicatedLog();
306
307         public  MockReplicatedLogBuilder createEntries(int start, int end, int term) {
308             for (int i=start; i<end; i++) {
309                 this.mockLog.append(new ReplicatedLogImplEntry(i, term, new MockRaftActorContext.MockPayload(Integer.toString(i))));
310             }
311             return this;
312         }
313
314         public  MockReplicatedLogBuilder addEntry(int index, int term, MockPayload payload) {
315             this.mockLog.append(new ReplicatedLogImplEntry(index, term, payload));
316             return this;
317         }
318
319         public ReplicatedLog build() {
320             return this.mockLog;
321         }
322     }
323
324     @Override
325     public void setCurrentBehavior(final RaftActorBehavior behavior) {
326         super.setCurrentBehavior(behavior);
327     }
328 }