2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.controller.cluster.raft;
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;
20 import org.opendaylight.controller.cluster.NonPersistentDataProvider;
21 import org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior;
22 import org.opendaylight.controller.cluster.raft.policy.RaftPolicy;
23 import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
27 public class MockRaftActorContext extends RaftActorContextImpl {
28 private static final Logger LOG = LoggerFactory.getLogger(MockRaftActorContext.class);
30 private ActorSystem system;
31 private RaftPolicy raftPolicy;
33 private static ElectionTerm newElectionTerm() {
34 return new ElectionTerm() {
35 private long currentTerm = 1;
36 private String votedFor = "";
39 public long getCurrentTerm() {
44 public String getVotedFor() {
49 public void update(long newTerm, String newVotedFor) {
50 this.currentTerm = newTerm;
51 this.votedFor = newVotedFor;
53 // TODO : Write to some persistent state
56 @Override public void updateAndPersist(long newTerm, String newVotedFor) {
57 update(newTerm, newVotedFor);
62 public MockRaftActorContext() {
63 super(null, null, "test", newElectionTerm(), -1, -1, new HashMap<>(),
64 new DefaultConfigParamsImpl(), new NonPersistentDataProvider(), LOG);
65 setReplicatedLog(new MockReplicatedLogBuilder().build());
68 public MockRaftActorContext(String id, ActorSystem system, ActorRef actor) {
69 super(actor, null, id, newElectionTerm(), -1, -1, new HashMap<>(),
70 new DefaultConfigParamsImpl(), new NonPersistentDataProvider(), LOG);
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 setCommitIndex(replicatedLog.lastIndex());
85 setLastApplied(replicatedLog.lastIndex());
88 @Override public ActorRef actorOf(Props props) {
89 return system.actorOf(props);
92 @Override public ActorSelection actorSelection(String path) {
93 return system.actorSelection(path);
96 @Override public ActorSystem getActorSystem() {
100 @Override public ActorSelection getPeerActorSelection(String peerId) {
101 String peerAddress = getPeerAddress(peerId);
102 if (peerAddress != null) {
103 return actorSelection(peerAddress);
108 public void setPeerAddresses(Map<String, String> peerAddresses) {
109 for (String id: getPeerIds()) {
113 for (Map.Entry<String, String> e: peerAddresses.entrySet()) {
114 addToPeers(e.getKey(), e.getValue(), VotingState.VOTING);
119 public SnapshotManager getSnapshotManager() {
120 SnapshotManager snapshotManager = super.getSnapshotManager();
121 snapshotManager.setCreateSnapshotRunnable(() -> { });
122 return snapshotManager;
126 public RaftPolicy getRaftPolicy() {
127 return raftPolicy != null ? raftPolicy : super.getRaftPolicy();
130 public void setRaftPolicy(RaftPolicy raftPolicy) {
131 this.raftPolicy = raftPolicy;
134 public static class SimpleReplicatedLog extends AbstractReplicatedLogImpl {
136 public int dataSize() {
141 public void captureSnapshotIfReady(ReplicatedLogEntry replicatedLogEntry) {
145 public boolean removeFromAndPersist(long index) {
146 return removeFrom(index) >= 0;
150 public void appendAndPersist(
151 ReplicatedLogEntry replicatedLogEntry) {
152 append(replicatedLogEntry);
156 @SuppressWarnings("checkstyle:IllegalCatch")
157 public void appendAndPersist(ReplicatedLogEntry replicatedLogEntry, Procedure<ReplicatedLogEntry> callback) {
158 append(replicatedLogEntry);
160 if (callback != null) {
162 callback.apply(replicatedLogEntry);
163 } catch (Exception e) {
164 Throwables.propagate(e);
170 public static class MockPayload extends Payload implements Serializable {
171 private static final long serialVersionUID = 3121380393130864247L;
172 private String value = "";
175 public MockPayload() {
178 public MockPayload(String data) {
180 size = value.length();
183 public MockPayload(String data, int size) {
194 public String toString() {
199 public int hashCode() {
200 final int prime = 31;
202 result = prime * result + (value == null ? 0 : value.hashCode());
207 public boolean equals(Object obj) {
214 if (getClass() != obj.getClass()) {
217 MockPayload other = (MockPayload) obj;
219 if (other.value != null) {
222 } else if (!value.equals(other.value)) {
229 public static class MockReplicatedLogEntry implements ReplicatedLogEntry, Serializable {
230 private static final long serialVersionUID = 1L;
232 private final long term;
233 private final long index;
234 private final Payload data;
236 public MockReplicatedLogEntry(long term, long index, Payload data) {
243 @Override public Payload getData() {
247 @Override public long getTerm() {
251 @Override public long getIndex() {
257 return getData().size();
261 public int hashCode() {
262 final int prime = 31;
264 result = prime * result + (data == null ? 0 : data.hashCode());
265 result = prime * result + (int) (index ^ index >>> 32);
266 result = prime * result + (int) (term ^ term >>> 32);
271 public boolean equals(Object obj) {
278 if (getClass() != obj.getClass()) {
281 MockReplicatedLogEntry other = (MockReplicatedLogEntry) obj;
283 if (other.data != null) {
286 } else if (!data.equals(other.data)) {
289 if (index != other.index) {
292 if (term != other.term) {
299 public String toString() {
300 StringBuilder builder = new StringBuilder();
301 builder.append("MockReplicatedLogEntry [term=").append(term).append(", index=").append(index)
302 .append(", data=").append(data).append("]");
303 return builder.toString();
307 public static class MockReplicatedLogBuilder {
308 private final ReplicatedLog mockLog = new SimpleReplicatedLog();
310 public MockReplicatedLogBuilder createEntries(int start, int end, int term) {
311 for (int i = start; i < end; i++) {
312 this.mockLog.append(new ReplicatedLogImplEntry(i, term,
313 new MockRaftActorContext.MockPayload(Integer.toString(i))));
318 public MockReplicatedLogBuilder addEntry(int index, int term, MockPayload payload) {
319 this.mockLog.append(new ReplicatedLogImplEntry(index, term, payload));
323 public ReplicatedLog build() {
329 public void setCurrentBehavior(final RaftActorBehavior behavior) {
330 super.setCurrentBehavior(behavior);