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;
17 import com.google.protobuf.GeneratedMessage;
19 import java.io.Serializable;
20 import java.util.HashMap;
23 import org.opendaylight.controller.cluster.NonPersistentDataProvider;
24 import org.opendaylight.controller.cluster.raft.policy.RaftPolicy;
25 import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
26 import org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages;
27 import org.opendaylight.controller.protobuff.messages.cluster.raft.test.MockPayloadMessages;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
31 public class MockRaftActorContext extends RaftActorContextImpl {
32 private static final Logger LOG = LoggerFactory.getLogger(MockRaftActorContext.class);
34 private ActorSystem system;
35 private RaftPolicy raftPolicy;
37 private static ElectionTerm newElectionTerm() {
38 return new ElectionTerm() {
39 private long currentTerm = 1;
40 private String votedFor = "";
43 public long getCurrentTerm() {
48 public String getVotedFor() {
53 public void update(long currentTerm, String votedFor){
54 this.currentTerm = currentTerm;
55 this.votedFor = votedFor;
57 // TODO : Write to some persistent state
60 @Override public void updateAndPersist(long currentTerm,
62 update(currentTerm, votedFor);
67 public MockRaftActorContext(){
68 super(null, null, "test", newElectionTerm(), -1, -1, new HashMap<String, String>(),
69 new DefaultConfigParamsImpl(), new NonPersistentDataProvider(), LOG);
72 public MockRaftActorContext(String id, ActorSystem system, ActorRef actor){
73 super(actor, null, id, newElectionTerm(), -1, -1, new HashMap<String, String>(),
74 new DefaultConfigParamsImpl(), new NonPersistentDataProvider(), LOG);
82 public void initReplicatedLog(){
83 SimpleReplicatedLog replicatedLog = new SimpleReplicatedLog();
84 long term = getTermInformation().getCurrentTerm();
85 replicatedLog.append(new MockReplicatedLogEntry(term, 0, new MockPayload("1")));
86 replicatedLog.append(new MockReplicatedLogEntry(term, 1, new MockPayload("2")));
87 setReplicatedLog(replicatedLog);
90 @Override public ActorRef actorOf(Props props) {
91 return system.actorOf(props);
94 @Override public ActorSelection actorSelection(String path) {
95 return system.actorSelection(path);
98 @Override public ActorSystem getActorSystem() {
102 @Override public ActorSelection getPeerActorSelection(String peerId) {
103 String peerAddress = getPeerAddress(peerId);
104 if(peerAddress != null){
105 return actorSelection(peerAddress);
110 public void setPeerAddresses(Map<String, String> peerAddresses) {
111 for(String id: getPeerIds()) {
115 for(Map.Entry<String, String> e: peerAddresses.entrySet()) {
116 addToPeers(e.getKey(), e.getValue(), VotingState.VOTING);
121 public SnapshotManager getSnapshotManager() {
122 SnapshotManager snapshotManager = super.getSnapshotManager();
123 snapshotManager.setCreateSnapshotCallable(NoopProcedure.<Void>instance());
124 return snapshotManager;
128 public RaftPolicy getRaftPolicy() {
129 return raftPolicy != null ? raftPolicy : super.getRaftPolicy();
132 public void setRaftPolicy(RaftPolicy raftPolicy) {
133 this.raftPolicy = raftPolicy;
136 public static class SimpleReplicatedLog extends AbstractReplicatedLogImpl {
138 public void appendAndPersist(
139 ReplicatedLogEntry replicatedLogEntry) {
140 append(replicatedLogEntry);
144 public int dataSize() {
149 public void captureSnapshotIfReady(ReplicatedLogEntry replicatedLogEntry) {
152 @Override public void removeFromAndPersist(long index) {
157 public void appendAndPersist(ReplicatedLogEntry replicatedLogEntry, Procedure<ReplicatedLogEntry> callback) {
158 append(replicatedLogEntry);
160 if(callback != null) {
162 callback.apply(replicatedLogEntry);
163 } catch (Exception 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 s) {
180 size = value.length();
183 public MockPayload(String s, int size) {
188 @Override public Map<GeneratedMessage.GeneratedExtension<?, ?>, String> encode() {
189 Map<GeneratedMessage.GeneratedExtension<?, ?>, String> map = new HashMap<>();
190 map.put(MockPayloadMessages.value, value);
194 @Override public Payload decode(
195 AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload payloadProtoBuff) {
196 String value = payloadProtoBuff.getExtension(MockPayloadMessages.value);
206 @Override public String getClientPayloadClassName() {
207 return MockPayload.class.getName();
211 public String toString() {
216 public int hashCode() {
217 final int prime = 31;
219 result = prime * result + ((value == null) ? 0 : value.hashCode());
224 public boolean equals(Object obj) {
231 if (getClass() != obj.getClass()) {
234 MockPayload other = (MockPayload) obj;
236 if (other.value != null) {
239 } else if (!value.equals(other.value)) {
246 public static class MockReplicatedLogEntry implements ReplicatedLogEntry, Serializable {
247 private static final long serialVersionUID = 1L;
249 private final long term;
250 private final long index;
251 private final Payload data;
253 public MockReplicatedLogEntry(long term, long index, Payload data){
260 @Override public Payload getData() {
264 @Override public long getTerm() {
268 @Override public long getIndex() {
274 return getData().size();
278 public int hashCode() {
279 final int prime = 31;
281 result = prime * result + ((data == null) ? 0 : data.hashCode());
282 result = prime * result + (int) (index ^ (index >>> 32));
283 result = prime * result + (int) (term ^ (term >>> 32));
288 public boolean equals(Object obj) {
295 if (getClass() != obj.getClass()) {
298 MockReplicatedLogEntry other = (MockReplicatedLogEntry) obj;
300 if (other.data != null) {
303 } else if (!data.equals(other.data)) {
306 if (index != other.index) {
309 if (term != other.term) {
316 public String toString() {
317 StringBuilder builder = new StringBuilder();
318 builder.append("MockReplicatedLogEntry [term=").append(term).append(", index=").append(index)
319 .append(", data=").append(data).append("]");
320 return builder.toString();
324 public static class MockReplicatedLogBuilder {
325 private final ReplicatedLog mockLog = new SimpleReplicatedLog();
327 public MockReplicatedLogBuilder createEntries(int start, int end, int term) {
328 for (int i=start; i<end; i++) {
329 this.mockLog.append(new ReplicatedLogImplEntry(i, term, new MockRaftActorContext.MockPayload(Integer.toString(i))));
334 public MockReplicatedLogBuilder addEntry(int index, int term, MockPayload payload) {
335 this.mockLog.append(new ReplicatedLogImplEntry(index, term, payload));
339 public ReplicatedLog build() {