65f0a624e6b83c6a3fb3cfff52a00d9d64c55850
[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 com.google.common.base.Throwables;
17 import java.io.Serializable;
18 import java.util.HashMap;
19 import java.util.Map;
20 import org.opendaylight.controller.cluster.NonPersistentDataProvider;
21 import org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior;
22 import org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry;
23 import org.opendaylight.controller.cluster.raft.policy.RaftPolicy;
24 import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 public class MockRaftActorContext extends RaftActorContextImpl {
29     private static final Logger LOG = LoggerFactory.getLogger(MockRaftActorContext.class);
30
31     private ActorSystem system;
32     private RaftPolicy raftPolicy;
33
34     private static ElectionTerm newElectionTerm() {
35         return new ElectionTerm() {
36             private long currentTerm = 1;
37             private String votedFor = "";
38
39             @Override
40             public long getCurrentTerm() {
41                 return currentTerm;
42             }
43
44             @Override
45             public String getVotedFor() {
46                 return votedFor;
47             }
48
49             @Override
50             public void update(long newTerm, String newVotedFor) {
51                 this.currentTerm = newTerm;
52                 this.votedFor = newVotedFor;
53
54                 // TODO : Write to some persistent state
55             }
56
57             @Override public void updateAndPersist(long newTerm, String newVotedFor) {
58                 update(newTerm, newVotedFor);
59             }
60         };
61     }
62
63     public MockRaftActorContext() {
64         super(null, null, "test", newElectionTerm(), -1, -1, new HashMap<>(),
65                 new DefaultConfigParamsImpl(), new NonPersistentDataProvider(), LOG);
66         setReplicatedLog(new MockReplicatedLogBuilder().build());
67     }
68
69     public MockRaftActorContext(String id, ActorSystem system, ActorRef actor) {
70         super(actor, null, id, newElectionTerm(), -1, -1, new HashMap<>(),
71                 new DefaultConfigParamsImpl(), new NonPersistentDataProvider(), LOG);
72
73         this.system = system;
74
75         initReplicatedLog();
76     }
77
78
79     public void initReplicatedLog() {
80         SimpleReplicatedLog replicatedLog = new SimpleReplicatedLog();
81         long term = getTermInformation().getCurrentTerm();
82         replicatedLog.append(new SimpleReplicatedLogEntry(0, term, new MockPayload("1")));
83         replicatedLog.append(new SimpleReplicatedLogEntry(1, term, new MockPayload("2")));
84         setReplicatedLog(replicatedLog);
85         setCommitIndex(replicatedLog.lastIndex());
86         setLastApplied(replicatedLog.lastIndex());
87     }
88
89     @Override public ActorRef actorOf(Props props) {
90         return system.actorOf(props);
91     }
92
93     @Override public ActorSelection actorSelection(String path) {
94         return system.actorSelection(path);
95     }
96
97     @Override public ActorSystem getActorSystem() {
98         return this.system;
99     }
100
101     @Override public ActorSelection getPeerActorSelection(String peerId) {
102         String peerAddress = getPeerAddress(peerId);
103         if (peerAddress != null) {
104             return actorSelection(peerAddress);
105         }
106         return null;
107     }
108
109     public void setPeerAddresses(Map<String, String> peerAddresses) {
110         for (String id: getPeerIds()) {
111             removePeer(id);
112         }
113
114         for (Map.Entry<String, String> e: peerAddresses.entrySet()) {
115             addToPeers(e.getKey(), e.getValue(), VotingState.VOTING);
116         }
117     }
118
119     @Override
120     public SnapshotManager getSnapshotManager() {
121         SnapshotManager snapshotManager = super.getSnapshotManager();
122         snapshotManager.setCreateSnapshotRunnable(() -> { });
123         return snapshotManager;
124     }
125
126     @Override
127     public RaftPolicy getRaftPolicy() {
128         return raftPolicy != null ? raftPolicy : super.getRaftPolicy();
129     }
130
131     public void setRaftPolicy(RaftPolicy raftPolicy) {
132         this.raftPolicy = raftPolicy;
133     }
134
135     public static class SimpleReplicatedLog extends AbstractReplicatedLogImpl {
136         @Override
137         public int dataSize() {
138             return -1;
139         }
140
141         @Override
142         public void captureSnapshotIfReady(ReplicatedLogEntry replicatedLogEntry) {
143         }
144
145         @Override
146         public boolean removeFromAndPersist(long index) {
147             return removeFrom(index) >= 0;
148         }
149
150         @Override
151         @SuppressWarnings("checkstyle:IllegalCatch")
152         public boolean appendAndPersist(ReplicatedLogEntry replicatedLogEntry, Procedure<ReplicatedLogEntry> callback,
153                 boolean doAsync) {
154             append(replicatedLogEntry);
155
156             if (callback != null) {
157                 try {
158                     callback.apply(replicatedLogEntry);
159                 } catch (Exception e) {
160                     Throwables.propagate(e);
161                 }
162             }
163
164             return true;
165         }
166     }
167
168     public static class MockPayload extends Payload implements Serializable {
169         private static final long serialVersionUID = 3121380393130864247L;
170         private String value = "";
171         private int size;
172
173         public MockPayload() {
174         }
175
176         public MockPayload(String data) {
177             this.value = data;
178             size = value.length();
179         }
180
181         public MockPayload(String data, int size) {
182             this(data);
183             this.size = size;
184         }
185
186         @Override
187         public int size() {
188             return size;
189         }
190
191         @Override
192         public String toString() {
193             return value;
194         }
195
196         @Override
197         public int hashCode() {
198             final int prime = 31;
199             int result = 1;
200             result = prime * result + (value == null ? 0 : value.hashCode());
201             return result;
202         }
203
204         @Override
205         public boolean equals(Object obj) {
206             if (this == obj) {
207                 return true;
208             }
209             if (obj == null) {
210                 return false;
211             }
212             if (getClass() != obj.getClass()) {
213                 return false;
214             }
215             MockPayload other = (MockPayload) obj;
216             if (value == null) {
217                 if (other.value != null) {
218                     return false;
219                 }
220             } else if (!value.equals(other.value)) {
221                 return false;
222             }
223             return true;
224         }
225     }
226
227     public static class MockReplicatedLogBuilder {
228         private final ReplicatedLog mockLog = new SimpleReplicatedLog();
229
230         public  MockReplicatedLogBuilder createEntries(int start, int end, int term) {
231             for (int i = start; i < end; i++) {
232                 this.mockLog.append(new SimpleReplicatedLogEntry(i, term,
233                         new MockRaftActorContext.MockPayload(Integer.toString(i))));
234             }
235             return this;
236         }
237
238         public  MockReplicatedLogBuilder addEntry(int index, int term, MockPayload payload) {
239             this.mockLog.append(new SimpleReplicatedLogEntry(index, term, payload));
240             return this;
241         }
242
243         public ReplicatedLog build() {
244             return this.mockLog;
245         }
246     }
247
248     @Override
249     public void setCurrentBehavior(final RaftActorBehavior behavior) {
250         super.setCurrentBehavior(behavior);
251     }
252 }