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 java.io.Serializable;
17 import java.util.HashMap;
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;
26 public class MockRaftActorContext extends RaftActorContextImpl {
27 private static final Logger LOG = LoggerFactory.getLogger(MockRaftActorContext.class);
29 private ActorSystem system;
30 private RaftPolicy raftPolicy;
32 private static ElectionTerm newElectionTerm() {
33 return new ElectionTerm() {
34 private long currentTerm = 1;
35 private String votedFor = "";
38 public long getCurrentTerm() {
43 public String getVotedFor() {
48 public void update(long currentTerm, String votedFor){
49 this.currentTerm = currentTerm;
50 this.votedFor = votedFor;
52 // TODO : Write to some persistent state
55 @Override public void updateAndPersist(long currentTerm,
57 update(currentTerm, votedFor);
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());
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);
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());
87 @Override public ActorRef actorOf(Props props) {
88 return system.actorOf(props);
91 @Override public ActorSelection actorSelection(String path) {
92 return system.actorSelection(path);
95 @Override public ActorSystem getActorSystem() {
99 @Override public ActorSelection getPeerActorSelection(String peerId) {
100 String peerAddress = getPeerAddress(peerId);
101 if(peerAddress != null){
102 return actorSelection(peerAddress);
107 public void setPeerAddresses(Map<String, String> peerAddresses) {
108 for(String id: getPeerIds()) {
112 for(Map.Entry<String, String> e: peerAddresses.entrySet()) {
113 addToPeers(e.getKey(), e.getValue(), VotingState.VOTING);
118 public SnapshotManager getSnapshotManager() {
119 SnapshotManager snapshotManager = super.getSnapshotManager();
120 snapshotManager.setCreateSnapshotRunnable(() -> { });
121 return snapshotManager;
125 public RaftPolicy getRaftPolicy() {
126 return raftPolicy != null ? raftPolicy : super.getRaftPolicy();
129 public void setRaftPolicy(RaftPolicy raftPolicy) {
130 this.raftPolicy = raftPolicy;
133 public static class SimpleReplicatedLog extends AbstractReplicatedLogImpl {
135 public void appendAndPersist(
136 ReplicatedLogEntry replicatedLogEntry) {
137 append(replicatedLogEntry);
141 public int dataSize() {
146 public void captureSnapshotIfReady(ReplicatedLogEntry replicatedLogEntry) {
150 public boolean removeFromAndPersist(long index) {
151 return removeFrom(index) >= 0;
155 public void appendAndPersist(ReplicatedLogEntry replicatedLogEntry, Procedure<ReplicatedLogEntry> callback) {
156 append(replicatedLogEntry);
158 if(callback != null) {
160 callback.apply(replicatedLogEntry);
161 } catch (Exception e) {
168 public static class MockPayload extends Payload implements Serializable {
169 private static final long serialVersionUID = 3121380393130864247L;
170 private String value = "";
173 public MockPayload() {
176 public MockPayload(String s) {
178 size = value.length();
181 public MockPayload(String s, int size) {
192 public String toString() {
197 public int hashCode() {
198 final int prime = 31;
200 result = prime * result + ((value == null) ? 0 : value.hashCode());
205 public boolean equals(Object obj) {
212 if (getClass() != obj.getClass()) {
215 MockPayload other = (MockPayload) obj;
217 if (other.value != null) {
220 } else if (!value.equals(other.value)) {
227 public static class MockReplicatedLogEntry implements ReplicatedLogEntry, Serializable {
228 private static final long serialVersionUID = 1L;
230 private final long term;
231 private final long index;
232 private final Payload data;
234 public MockReplicatedLogEntry(long term, long index, Payload data){
241 @Override public Payload getData() {
245 @Override public long getTerm() {
249 @Override public long getIndex() {
255 return getData().size();
259 public int hashCode() {
260 final int prime = 31;
262 result = prime * result + ((data == null) ? 0 : data.hashCode());
263 result = prime * result + (int) (index ^ (index >>> 32));
264 result = prime * result + (int) (term ^ (term >>> 32));
269 public boolean equals(Object obj) {
276 if (getClass() != obj.getClass()) {
279 MockReplicatedLogEntry other = (MockReplicatedLogEntry) obj;
281 if (other.data != null) {
284 } else if (!data.equals(other.data)) {
287 if (index != other.index) {
290 if (term != other.term) {
297 public String toString() {
298 StringBuilder builder = new StringBuilder();
299 builder.append("MockReplicatedLogEntry [term=").append(term).append(", index=").append(index)
300 .append(", data=").append(data).append("]");
301 return builder.toString();
305 public static class MockReplicatedLogBuilder {
306 private final ReplicatedLog mockLog = new SimpleReplicatedLog();
308 public MockReplicatedLogBuilder createEntries(int start, int end, int term) {
309 for (int i=start; i<end; i++) {
310 this.mockLog.append(new ReplicatedLogImplEntry(i, term, new MockRaftActorContext.MockPayload(Integer.toString(i))));
315 public MockReplicatedLogBuilder addEntry(int index, int term, MockPayload payload) {
316 this.mockLog.append(new ReplicatedLogImplEntry(index, term, payload));
320 public ReplicatedLog build() {
326 public void setCurrentBehavior(final RaftActorBehavior behavior) {
327 super.setCurrentBehavior(behavior);