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 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;
23 import org.opendaylight.controller.cluster.NonPersistentDataProvider;
24 import org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior;
25 import org.opendaylight.controller.cluster.raft.persisted.ByteState;
26 import org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry;
27 import org.opendaylight.controller.cluster.raft.persisted.Snapshot.State;
28 import org.opendaylight.controller.cluster.raft.policy.RaftPolicy;
29 import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
33 public class MockRaftActorContext extends RaftActorContextImpl {
34 private static final Logger LOG = LoggerFactory.getLogger(MockRaftActorContext.class);
36 private ActorSystem system;
37 private RaftPolicy raftPolicy;
39 private static ElectionTerm newElectionTerm() {
40 return new ElectionTerm() {
41 private long currentTerm = 1;
42 private String votedFor = "";
45 public long getCurrentTerm() {
50 public String getVotedFor() {
55 public void update(long newTerm, String newVotedFor) {
56 this.currentTerm = newTerm;
57 this.votedFor = newVotedFor;
59 // TODO : Write to some persistent state
62 @Override public void updateAndPersist(long newTerm, String newVotedFor) {
63 update(newTerm, newVotedFor);
68 public MockRaftActorContext() {
69 super(null, null, "test", newElectionTerm(), -1, -1, new HashMap<>(),
70 new DefaultConfigParamsImpl(), new NonPersistentDataProvider(), applyState -> { }, LOG);
71 setReplicatedLog(new MockReplicatedLogBuilder().build());
74 public MockRaftActorContext(String id, ActorSystem system, ActorRef actor) {
75 super(actor, null, id, newElectionTerm(), -1, -1, new HashMap<>(),
76 new DefaultConfigParamsImpl(), new NonPersistentDataProvider(),
77 applyState -> actor.tell(applyState, actor), LOG);
85 public void initReplicatedLog() {
86 SimpleReplicatedLog replicatedLog = new SimpleReplicatedLog();
87 long term = getTermInformation().getCurrentTerm();
88 replicatedLog.append(new SimpleReplicatedLogEntry(0, term, new MockPayload("1")));
89 replicatedLog.append(new SimpleReplicatedLogEntry(1, term, new MockPayload("2")));
90 setReplicatedLog(replicatedLog);
91 setCommitIndex(replicatedLog.lastIndex());
92 setLastApplied(replicatedLog.lastIndex());
95 @Override public ActorRef actorOf(Props props) {
96 return system.actorOf(props);
99 @Override public ActorSelection actorSelection(String path) {
100 return system.actorSelection(path);
103 @Override public ActorSystem getActorSystem() {
107 @Override public ActorSelection getPeerActorSelection(String peerId) {
108 String peerAddress = getPeerAddress(peerId);
109 if (peerAddress != null) {
110 return actorSelection(peerAddress);
115 public void setPeerAddresses(Map<String, String> peerAddresses) {
116 for (String id: getPeerIds()) {
120 for (Map.Entry<String, String> e: peerAddresses.entrySet()) {
121 addToPeers(e.getKey(), e.getValue(), VotingState.VOTING);
126 public SnapshotManager getSnapshotManager() {
127 SnapshotManager snapshotManager = super.getSnapshotManager();
128 snapshotManager.setCreateSnapshotConsumer(out -> { });
130 snapshotManager.setSnapshotCohort(new RaftActorSnapshotCohort() {
132 public State deserializeSnapshot(ByteSource snapshotBytes) throws IOException {
133 return ByteState.of(snapshotBytes.read());
137 public void createSnapshot(ActorRef actorRef, java.util.Optional<OutputStream> installSnapshotStream) {
141 public void applySnapshot(State snapshotState) {
145 return snapshotManager;
149 public RaftPolicy getRaftPolicy() {
150 return raftPolicy != null ? raftPolicy : super.getRaftPolicy();
153 public void setRaftPolicy(RaftPolicy raftPolicy) {
154 this.raftPolicy = raftPolicy;
157 public static class SimpleReplicatedLog extends AbstractReplicatedLogImpl {
159 public int dataSize() {
164 public void captureSnapshotIfReady(ReplicatedLogEntry replicatedLogEntry) {
168 public boolean shouldCaptureSnapshot(long logIndex) {
173 public boolean removeFromAndPersist(long index) {
174 return removeFrom(index) >= 0;
178 @SuppressWarnings("checkstyle:IllegalCatch")
179 public boolean appendAndPersist(ReplicatedLogEntry replicatedLogEntry, Procedure<ReplicatedLogEntry> callback,
181 append(replicatedLogEntry);
183 if (callback != null) {
185 callback.apply(replicatedLogEntry);
186 } catch (Exception e) {
187 Throwables.propagate(e);
195 public static class MockPayload extends Payload implements Serializable {
196 private static final long serialVersionUID = 3121380393130864247L;
197 private String value = "";
200 public MockPayload() {
203 public MockPayload(String data) {
205 size = value.length();
208 public MockPayload(String data, int size) {
219 public String toString() {
224 public int hashCode() {
225 final int prime = 31;
227 result = prime * result + (value == null ? 0 : value.hashCode());
232 public boolean equals(Object obj) {
239 if (getClass() != obj.getClass()) {
242 MockPayload other = (MockPayload) obj;
244 if (other.value != null) {
247 } else if (!value.equals(other.value)) {
254 public static class MockReplicatedLogBuilder {
255 private final ReplicatedLog mockLog = new SimpleReplicatedLog();
257 public MockReplicatedLogBuilder createEntries(int start, int end, int term) {
258 for (int i = start; i < end; i++) {
259 this.mockLog.append(new SimpleReplicatedLogEntry(i, term,
260 new MockRaftActorContext.MockPayload(Integer.toString(i))));
265 public MockReplicatedLogBuilder addEntry(int index, int term, MockPayload payload) {
266 this.mockLog.append(new SimpleReplicatedLogEntry(index, term, payload));
270 public ReplicatedLog build() {
276 public void setCurrentBehavior(final RaftActorBehavior behavior) {
277 super.setCurrentBehavior(behavior);