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

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.